﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using System.Threading;
using SerialPortHelperLib;
using System.IO.Ports;
using System.Configuration;
using XModem.library;
using System.IO;
using System.Text.RegularExpressions;
using XChip_Common;
using System.Runtime.InteropServices;
using System.Diagnostics;
using ICSharpCode.SharpZipLib.Zip;


namespace XChipTool
{
    public partial class XModemForm : DevExpress.XtraEditors.XtraUserControl
    {

        #region 全局变量
        //SendSetXModemClick
        //public delegate void SendEventXModemFormClick(bool isOpen);

        //public event SendEventXModemFormClick SendSetXModemClick;

        public delegate void SendEventChangeSysClk();

        public event SendEventChangeSysClk SendChangeSysClk;

        public delegate void OpenPortButtonClickEventHandler(bool isOpen);

        public event OpenPortButtonClickEventHandler OpenPortButtonClick;

        private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();

        string BaudRate;
        string Ports;

        int FlashSize = 0;

        List<string> patchheader = new List<string>();
        List<FlashSettingModel> fsmList = new List<FlashSettingModel>();
        //private  Port port = new Port();
        private bool isFinish=false;

        private FlashBase fb;
        /// <summary>
        /// 创建上下文同步
        /// </summary>
        private SynchronizationContext context;
        /// <summary>
        /// 导出
        /// </summary>
        private string txPath = string.Empty;
        /// <summary>
        /// 烧写
        /// </summary>
        private string rxPath = string.Empty;
        /// <summary>
        /// 系统频率
        /// </summary>
        private string fsysPath = string.Empty;
        private int FSysFArmsum = 0;


        //定义SerialPortHelper类
        private SerialPortHelper serialPort1;
        private SerialPortHelper serialPort2;
        //用来定义发送配置文件类 不能使用多线程 使用的话发送类以前的代码都需要修改 目前多建立一个本地串口
        public SerialPort sPortTemp;
        //爆序号
        private int PackageTemp = 0;
        //判断是c 还是nak
        private int useCRC = -1;
        //盘是1kxmodem 还是xmodem
        private bool useBlock1K;
        //用来存储接收到的文件
        private List<List<byte>> receiveList;
        //是否结束当前发送
        private bool isSend = true;
        //是否开启打印
        private bool isPrintShow = true;

        //记录是否使用USB设备读写
        public bool IsUsbOpen = false;
        private static TaskCompletionSource<bool> _writeTaskCompletionSource = new TaskCompletionSource<bool>();
        #endregion
        public XModemForm()
        {
            InitializeComponent();
        }
        public XModemForm(SerialPort _sPortTemp)
        {
            sPortTemp = _sPortTemp;
            
            InitializeComponent();
        }

        private void XModemForm_Load(object sender, EventArgs e)
        {

            Task.Run(() => {

                this.Invoke((EventHandler)delegate {

                    groupControl2.Hide();
                    comBoxPorts.Properties.ValueMember = "ValueMember";
                    comBoxPorts.Properties.DisplayMember = "DisplayMember";
                    comBoxPorts.Properties.DataSource = XModem.library.Port.GetPorts();
                    comBoxPorts.ItemIndex = -1;


                    comBoxBaudRate.Properties.ValueMember = "ValueMember";
                    comBoxBaudRate.Properties.DisplayMember = "DisplayMember";
                    comBoxBaudRate.Properties.DataSource = XModem.library.Port.GetRate();
                    comBoxBaudRate.ItemIndex = 5;


                    comBoxParity.Properties.ValueMember = "ValueMember";
                    comBoxParity.Properties.DisplayMember = "DisplayMember";
                    comBoxParity.Properties.DataSource = XModem.library.Port.GetParity();
                    comBoxParity.ItemIndex = 2;


                    comBoxDataBits.Properties.ValueMember = "ValueMember";
                    comBoxDataBits.Properties.DisplayMember = "DisplayMember";
                    comBoxDataBits.Properties.DataSource = XModem.library.Port.GetDataBits();
                    comBoxDataBits.ItemIndex = 0;

                    comBoxStopBits.Properties.ValueMember = "ValueMember";
                    comBoxStopBits.Properties.DisplayMember = "DisplayMember";
                    comBoxStopBits.Properties.DataSource = XModem.library.Port.GetStopBits();
                    comBoxStopBits.ItemIndex = 0;

                    //comBoxFSys.Properties.ValueMember = "ValueMember";
                    //comBoxFSys.Properties.DisplayMember = "DisplayMember";
                    //comBoxFSys.Properties.DataSource = Port.GetFSYS();
                    //comBoxFSys.ItemIndex = -1;

                    //comBoxFArm.Properties.ValueMember = "ValueMember";
                    //comBoxFArm.Properties.DisplayMember = "DisplayMember";
                    //comBoxFArm.Properties.DataSource = Port.GetFSYS();
                    //comBoxFArm.ItemIndex = -1;

                    comBoxAgreement.Properties.ValueMember = "ValueMember";
                    comBoxAgreement.Properties.DisplayMember = "DisplayMember";
                    comBoxAgreement.Properties.DataSource = XModem.library.Port.GetAgreement();
                    comBoxAgreement.ItemIndex = 0;

                    //设置文件只读
                    textEdit1.ReadOnly = true;
                    textEdit2.ReadOnly = true;
                    subsectiontext.Enabled = false;
                    //初始化串口
                    //Port.SelectedPort = new SerialPort();
                    //如果是这样，我们可以通过创建SynchronizationContext来简化
                    if (context == null)
                    {
                        context = SynchronizationContext.Current;
                    }

                    serialPort1 = new SerialPortHelper();
                    //发送使用的串口通讯
                    serialPort1.BindSerialPortDataReceivedProcessEvent(new SerialPortHelper.DelegateSerialPortDataReceivedProcessEvent(SerialPortDataReceivedProcess1));
                    serialPort1.BindSerialPortErrorEvent(new SerialPortHelper.DelegateSerialPortErrorEvent(SerialPortErrorProcess));
                    serialPort1.SerialReceviedTimeInterval = 10; //接收数据时间
                    serialPort1.SerialReceviedTimeInterval = 1;  //发送数据时间
                                                                 //serialPort1.SPort.WriteTimeout = 3000;
                                                                 //serialPort1.SPort.ReadTimeout = 3000;
                    serialPort2 = new SerialPortHelper();
                    //接收使用的串口通讯
                    serialPort2.BindSerialPortDataReceivedProcessEvent(new SerialPortHelper.DelegateSerialPortDataReceivedProcessEvent(SerialPortDataReceivedProcess2));
                    serialPort2.BindSerialPortErrorEvent(new SerialPortHelper.DelegateSerialPortErrorEvent(SerialPortErrorProcess));
                    serialPort2.SerialReceviedTimeInterval = 1; //接收数据时间
                    serialPort2.SerialReceviedTimeInterval = 1;  //发送数据时间
                                                                 //serialPort2.SPort.WriteTimeout = 3000;
                                                                 //serialPort2.SPort.ReadTimeout = 3000;
                    jzTxt.Text = ConfigurationManager.AppSettings["PAD_CLK"];
                    sPortTemp = new SerialPort();

                    var sizelist = comboBoxFlashSize.Properties.DataSource as List<TreeListValue>;
                    if (null == sizelist)
                    {
                        List<TreeListValue> list = new List<TreeListValue>();
                        list.Add(new TreeListValue() { DisplayMember = "4M", ValueMember = $"{4 * 1024 * 1024}" });
                        list.Add(new TreeListValue() { DisplayMember = "8M", ValueMember = $"{8 * 1024 * 1024}" });
                        comboBoxFlashSize.Properties.DataSource = list;
                        comboBoxFlashSize.Properties.ValueMember = "ValueMember";
                        comboBoxFlashSize.Properties.DisplayMember = "DisplayMember";
                    }
                    comboBoxFlashSize.ItemIndex = 1;

                });
            });
            if (GetConfigValue("IsSerial") == "USB")
            {
                btnFlashWriteFile.Visible = true;
            }
            else
            {
                btnFlashWriteFile.Visible = false;
            }
            if (GetConfigValue("IsVisible") == "1")
            {
                groupControl1.Visible = true;
            }
            else
            {
                groupControl1.Visible = false;
            }

        }
        private string GetConfigValue(string strKey)
        {
            var configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            var settings = configFile.AppSettings.Settings;

            return settings[strKey].Value;
        }
        #region 串口错误事件
        /// <summary>
        /// 串口错误事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="enumError"></param>
        /// <param name="strError"></param>
        private void SerialPortErrorProcess(object sender, enumSerialError enumError, string strError)
        {
            this.Invoke(new Action(() =>
            {
                switch (enumError)
                {
                    case enumSerialError.LinkError:
                        string str = string.Empty;
                        if (!isFinish)
                        {
                            serialPort1.CloseCom(out str);
                            Fb_SendEvent(string.Format("串口1错误：{0}", str));
                            serialPort2.CloseCom(out str);
                            Fb_SendEvent(string.Format("串口2错误：{0}", str));
                        }                       
                        break;
                    case enumSerialError.WriteError:
                        Fb_SendEvent(string.Format("发送错误：{0}", strError));
                        break;
                    case enumSerialError.ReceivedError:
                        Fb_SendEvent(string.Format("接收错误：{0}", strError));
                        break;
                    default:
                        break;
                }
            }));
        }

        #endregion
        #region 接收数据处理
        /// <summary>
        /// 记录上次一次发送序号
        /// </summary>
        private int tempReceived = 0;
        /// <summary>
        /// 记录当接收长度超过255重新开始计数
        /// </summary>
        private int tempSize = 0;

        List<List<byte>> templists = new List<List<byte>>();
        List<XmodemRequest> rxtemplists = new List<XmodemRequest>();
        /// <summary>
        /// 导出数据处理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="arrDataReceived"></param>
        private void SerialPortDataReceivedProcess2(object sender, byte[] arrDataReceived)
        {
            this.Invoke(new Action(() =>
            {

                try
                {
                    if (arrDataReceived.Length != (useBlock1K ? 1028 : 132))
                    {
                        if (arrDataReceived.First() == 04)//表示结束接收
                        {
                            serialPort2.Write(new byte[] { 0x06, 0x06, 0x06, 0x06 }); //告诉终端结束这次发送
                            Thread.Sleep(1000);                            
                            receivePath();
                            serialPort2.SPort.DiscardInBuffer();
                            serialPort2.SPort.DiscardOutBuffer();
                            binPBC.Position = binPBC.Properties.Maximum;//设置进度条100%
                            string msg = "导出完成！";
                            Fb_SendEvent(msg);                            
                            serialPort2.CloseCom(out msg);
                            Fb_SendEvent(msg);
                            simpleButton4.Text = "导出";
                            OpenCloseFormButton(true);
                            isFinish = true;
                            //DevExpress.XtraEditors.XtraMessageBox.Show("导出完成，请重启设备", "提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);                            
                        }
                        else
                        {
                            string msg = "->获取数据长度不够，重新获取！";
                            Fb_SendEvent(string.Format(msg));
                            simpleButton4.Text = "导出";
                            serialPort2.CloseCom(out msg);
                            //serialPort2.Write(new byte[] { 0x15 }); //重新NAk获取
                        }
                        return;
                    }

                    if (arrDataReceived.First() == 04)//表示结束接收
                    {
                        serialPort2.Write(new byte[] { 0x06, 0x06, 0x06, 0x06 }); //告诉终端结束这次发送
                                                                                  //休眠下 导入到文件
                        Thread.Sleep(1000);
                        receivePath();
                        serialPort2.SPort.DiscardInBuffer();
                        serialPort2.SPort.DiscardOutBuffer();
                        binPBC.Position = binPBC.Properties.Maximum;//设置进度条100%
                        string msg = "导出完成！";
                        Fb_SendEvent(msg);
                        serialPort2.CloseCom(out msg);
                        Fb_SendEvent(msg);
                        simpleButton4.Text = "导出";
                        OpenCloseFormButton(true);
                        isFinish = true;
                        DevExpress.XtraEditors.XtraMessageBox.Show("导出完成，请重启设备", "提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                        return;
                    }
                    //接收数据业务处理部分
                    else if (arrDataReceived.First() == (useBlock1K ? 2 : 1)) //如果是1k 等于2 如果是k 就是1 处理头部分文件
                    {                        
                        List<byte> tembyte = new List<byte>();
                        XmodemRequest xRequest = new XmodemRequest();
                        xRequest.ControlCharacter = arrDataReceived.First();
                        xRequest.PackageNo = arrDataReceived[1];
                        var tempIndex = Convert.ToInt32(xRequest.PackageNo) - 1; //接收第二位
                        xRequest.PackageInverseNo = arrDataReceived[2];

                        byte lastCrc;
                        //判断校验位
                        if (useBlock1K)
                        {
                            xRequest.DataList = arrDataReceived.Skip(3).Take(1024).ToList();
                            tembyte.AddRange(arrDataReceived.Skip(3).Take(1024));
                            xRequest.CheckBit = new byte[] { arrDataReceived.Skip(1027).Take(1).First() };
                            lastCrc = arrDataReceived.Skip(1027).Take(1).First(); //获取校验位
                        }
                        else
                        {
                            xRequest.DataList = arrDataReceived.Skip(3).Take(128).ToList();
                            tembyte.AddRange(arrDataReceived.Skip(3).Take(128));
                            xRequest.CheckBit = new byte[] { arrDataReceived.Skip(131).Take(1).First() };
                            lastCrc = arrDataReceived.Skip(131).Take(1).First(); //获取校验位
                        }
                        if (lastCrc != BitConverter.GetBytes(XModem.library.Port.GetCkSum(tembyte.ToArray()))[0]) //判断校验位是否正确
                        {
                            Fb_SendEvent(string.Format("校验位不正确重新发送NAK"));                            
                            serialPort2.Write(new byte[] { 0x15 }); //重新NAk获取

                        }
                        else
                        {                            
                            serialPort2.Write(new byte[] { 0x06 }); //获取下一个
                            if (tempIndex != tempReceived)
                            {
                                tempSize++;
                                binPBC.Position += 1;
                            }

                            xRequest.No = tempSize;
                            Fb_SendEvent(string.Format("->导出数据{0}包", tempSize));

                            //templists.Add(tembyte.ToList()); //用来查看包
                            rxtemplists.Add(xRequest);
                            tempReceived = tempIndex;
                        }

                    }
                    else if (arrDataReceived.First() == 24)
                    {
                        simpleButton4.Text = "导出";
                        string msg = "连接超时！";
                        Fb_SendEvent(msg);
                        serialPort2.CloseCom(out msg);
                        Fb_SendEvent(msg);
                        OpenCloseFormButton(true);
                    }
                    else
                    {
                        serialPort2.Write(new byte[] { 0x15 }); //重新NAk获取
                    }

                    if (!isSend)
                    {
                        Thread.Sleep(1000);
                        binPBC.Position = binPBC.Properties.Maximum;//设置进度条100%
                        simpleButton4.Text = "导出";
                        serialPort2.Write(new byte[] { 0x18 }); //告诉终端结束这次发送
                        Thread.Sleep(50);
                        serialPort2.Write(new byte[] { 0x18 }); //告诉终端结束这次发送
                        Thread.Sleep(50);
                        serialPort2.Write(new byte[] { 0x18 }); //告诉终端结束这次发送
                        Thread.Sleep(50);
                        serialPort2.Write(new byte[] { 0x18 }); //告诉终端结束这次发送
                        Thread.Sleep(50);
                        string msg = "取消命令已发送！";
                        Fb_SendEvent(msg);
                        serialPort2.CloseCom(out msg);
                        Fb_SendEvent(msg);
                    }
                }
                catch (Exception ex)
                {
                    simpleButton4.Text = "导出";
                    serialPort2.DiscardInBuffer();
                    string msg = "导出错误信息:";
                    Fb_SendEvent(msg);
                    serialPort2.CloseCom(out msg);
                    OpenCloseFormButton(true);
                    Fb_SendEvent(string.Format("导出错误信息：{0}", ex.Message.ToString()));
                }


            }));
        }
        private void receivePath()
        {
            //保存数据到路劲下
            //去除重复数据据
            rxtemplists = rxtemplists.Distinct(new ListByteComparer()).ToList();



            using (FileStream fs = new FileStream(textEdit2.Text, FileMode.Create))
            {
                using (BinaryWriter plik = new BinaryWriter(fs))
                {
                    //if (templists.Count>= receiveTempCout)
                    //{

                    var lastrx = rxtemplists.Last();
                    if (lastrx.DataList[0] == 0x1a && lastrx.DataList[1] == 0x0 && lastrx.DataList.Last() == 0x0)
                    {
                        rxtemplists.Remove(lastrx);
                    }

                    foreach (var item in rxtemplists)
                    {

                        foreach (var temD in item.DataList)
                        {

                            plik.Write(temD);
                        }
                    }

                }
            }

        }
        public class ListByteComparer : IEqualityComparer<XmodemRequest>
        {
            public bool Equals(XmodemRequest x, XmodemRequest y)
            {
                return x.No == y.No;
            }

            public int GetHashCode(XmodemRequest obj)
            {
                return obj.ToString().GetHashCode();
            }
        }
        /// <summary>
        /// 烧入
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="arrDataReceived"></param>
        private void SerialPortDataReceivedProcess1(object sender, byte[] arrDataReceived)
        {
            this.Invoke(new Action(() =>
            {
                try
                {
                  

                    if (!isSend)
                    {
                        serialPort1.Write(new byte[] { 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 });
                        Thread.Sleep(1000); //由于在多线程中  如果需要关闭就需要添加延迟 然在关闭
                        string msg = "烧写完成！";
                        Fb_SendEvent(msg);
                        serialPort1.CloseCom(out msg);
                        Fb_SendEvent(msg);
                        binPBC.Position = binPBC.Properties.Maximum; //设置进度条100%
                        simpleButton3.Text = "烧写";
                        //Fb_SendEvent("取消命令已发送！");
                        OpenCloseFormButton(true);
                        serialPort1.DiscardInBuffer();
                        isSend = true;
                    }
                    Fb_SendEvent(string.Format("->接收:{1}  烧入{0}次数。。。", PackageTemp, Convert.ToString(arrDataReceived[0], 16)));
                    //发送数据业务处理部分
                    switch (arrDataReceived[0])
                    {
                       
                        case 0x43: //表示c
                            {
                                useCRC = 0;

                                if (useBlock1K)
                                {
                                    serialPort1.WriteByte(XmodemData.xmodem1k_C[PackageTemp].ToArray());
                                }
                                else
                                {
                                    serialPort1.WriteByte(XmodemData.xmodem_C[PackageTemp].ToArray());
                                }
                              //  serialPort1.DiscardInBuffer();


                            }
                            break;                       
                        case 0x15: //表示nak
                            {
                                //serialPort1.WriteByte(new byte[] { 0x02 });
                                //Fb_SendEvent("发送0x02");
                                useCRC = 1;
                                if (useBlock1K)
                                {
                                    if (PackageTemp > 0)
                                    {
                                        serialPort1.WriteByte(XmodemData.xmodem1k_N[PackageTemp - 1].ToArray());
                                    }
                                    else
                                    {
                                        serialPort1.WriteByte(XmodemData.xmodem1k_N[PackageTemp].ToArray());
                                    }

                                }
                                else
                                {
                                    if (PackageTemp > 0)
                                    {
                                        serialPort1.WriteByte(XmodemData.xmodem_N[PackageTemp - 1].ToArray());
                                    }
                                    else
                                    {
                                        serialPort1.WriteByte(XmodemData.xmodem_N[PackageTemp].ToArray());
                                    }

                                }
                                //   serialPort1.DiscardInBuffer();
                               
                            }
                            break;                       
                        case 0x06: //表示ack
                            {

                                if (useBlock1K)
                                {
                                    if (PackageTemp > XmodemData.xmodem1k_C.Count - 1)
                                    {
                                        //////发送取消命令 EOT 0x04
                                        serialPort1.Write(new byte[] { 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 });
                                        //////这里关闭通讯 切换回以前的串口通讯
                                        Thread.Sleep(1000); //由于在多线程中  如果需要关闭就需要添加延迟 然在关闭
                                        string msg = "烧写完成！";
                                        Fb_SendEvent(msg);
                                        serialPort1.CloseCom(out msg);
                                        Fb_SendEvent(msg);
                                        binPBC.Position = binPBC.Properties.Maximum; //设置进度条100%
                                        simpleButton3.Text = "烧写";
                                        OpenCloseFormButton(true);
                                        isFinish = true;
                                        serialPort1.DiscardInBuffer();
                                        DevExpress.XtraEditors.XtraMessageBox.Show("烧写完成，请重启设备", "提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                                        //logger.Debug("烧写完成准备打开串口");
                                        //Thread.Sleep(200); //由于在多线程中  如果需要关闭就需要添加延迟 然在关闭
                                        //打开串口
                                        //if (null != OpenPortButtonClick)
                                        //{
                                        //    Thread.Sleep(100); //由于在多线程中  如果需要关闭就需要添加延迟 然在关闭
                                        //    OpenPortButtonClick(false);
                                        //    logger.Debug("打开串口完成");
                                        //}
                                        //Thread.Sleep(200); //由于在多线程中  如果需要关闭就需要添加延迟 然在关闭
                                        return;
                                    }
                                }
                                else
                                {
                                    if (PackageTemp > XmodemData.xmodem_C.Count - 1)
                                    {
                                        //////发送取消命令 EOT 0x04
                                        serialPort1.Write(new byte[] { 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 });
                                        //////这里关闭通讯 切换回以前的串口通讯
                                        Thread.Sleep(1000); //由于在多线程中  如果需要关闭就需要添加延迟 然在关闭
                                        string msg = "烧写完成！";
                                        Fb_SendEvent(msg);
                                        serialPort1.CloseCom(out msg);
                                        Fb_SendEvent(msg);
                                        binPBC.Position = binPBC.Properties.Maximum; //设置进度条100%
                                        simpleButton3.Text = "烧写";
                                        OpenCloseFormButton(true);
                                        isFinish = true;
                                        serialPort1.DiscardInBuffer();
                                        DevExpress.XtraEditors.XtraMessageBox.Show("烧写完成，请重启设备", "提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                                        break;
                                    }
                                }


                                if (useCRC == 0)
                                {
                                    if (useBlock1K)
                                    {
                                        serialPort1.WriteByte(XmodemData.xmodem1k_C[PackageTemp].ToArray());
                                    }
                                    else
                                    {
                                        serialPort1.WriteByte(XmodemData.xmodem_C[PackageTemp].ToArray());
                                    }
                                }
                                if (useCRC == 1)
                                {
                                    if (useBlock1K)
                                    {
                                        serialPort1.WriteByte(XmodemData.xmodem1k_N[PackageTemp].ToArray());
                                    }
                                    else
                                    {
                                        serialPort1.WriteByte(XmodemData.xmodem_N[PackageTemp].ToArray());
                                    }
                                }
                                //设置进度条
                                binPBC.Position += 1;
                                PackageTemp++;
                                // serialPort1.DiscardInBuffer();
                                //Thread.Sleep(16);
                            }
                            break;
                        case 0x18:
                            {
                                serialPort1.Write(new byte[] { 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 });
                                simpleButton3.Text = "烧写";
                                string msg = "烧写失败";
                                Fb_SendEvent(msg);
                                serialPort1.CloseCom(out msg);
                                Fb_SendEvent(msg);
                                serialPort1.DiscardInBuffer();
                                OpenCloseFormButton(true);
                            }
                            break;
                        default:
                            {
                                simpleButton3.Text = "烧写";
                                string msg = $"接收到错误指令{arrDataReceived[0]},无法继续，烧写失败";
                                Fb_SendEvent(msg);
                                serialPort1.CloseCom(out msg);
                                Fb_SendEvent(msg);
                                serialPort1.DiscardInBuffer();
                                OpenCloseFormButton(true);
                            }
                            break;
                    }

                }
                catch (Exception ex)
                {
                    simpleButton3.Text = "烧写";
                    string msg = "烧写失败";
                    serialPort1.DiscardInBuffer();
                    Fb_SendEvent(msg);
                    serialPort1.CloseCom(out msg);
                    Fb_SendEvent(string.Format("烧写错误信息：{0}", ex.Message.ToString()));
                }
            }));
        }
        #endregion
        private void Fb_SendEvent(string msg)
        {
            if (isPrintShow)
            {
                context.Post(t =>
                {
                    //操作
                    if (textBox_disp.GetLineFromCharIndex(textBox_disp.Text.Length) > 10000)
                    {
                        textBox_disp.Text = string.Empty;
                    }
                    //追加的形式添加到文本框末端，并滚动到最后。     
                    this.textBox_disp.AppendText(msg);
                    this.textBox_disp.AppendText("\r\n");
                    this.textBox_disp.SelectionStart = textBox_disp.Text.Length;
                    this.textBox_disp.ScrollToCaret();

            }, msg);
        }
        }
        /// <summary>
        /// 发送选择文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void simpleButton5_Click(object sender, EventArgs e)
        {
            //读取文件  选择bin文件 读取bin文件长度  生成文件夹
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            openFileDialog1.Filter = "Bin Files(*.bin)|*.bin|All Files(*.*)|*.*";
            if (openFileDialog1.ShowDialog() == DialogResult.OK)//用户是否选择确定
            {
                textEdit1.Text = openFileDialog1.FileName;
               
                SetTxRxPath();
            }
        }
        /// <summary>
        /// 接收文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void simpleButton6_Click(object sender, EventArgs e)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            //设置文件类型 
            sfd.Filter = "BIN文件（*.bin）|*.bin";
            //设置默认文件类型显示顺序 
            sfd.FilterIndex = 1;
            //保存对话框是否记忆上次打开的目录 
            sfd.RestoreDirectory = true;
            //设置文件名
            sfd.FileName = "Xchip_Output_" + DateTime.Now.ToString("yyyyMMddHHmms");
            var Save_BIN_Output_File_FileName_Path = string.Empty;
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                textEdit2.Text = sfd.FileName.ToString();
            }
        }
        /// <summary>
        /// 烧写
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void simpleButton3_Click(object sender, EventArgs e)
        {
            if (sPortTemp.IsOpen)
            {
                CalculationCrystalOscillator();
            }
            Thread.Sleep(100);
            comBoxFSys_EditValueChanged(null, null);
           
            SetTxRxPath();
            Ports = sPortTemp.PortName;
            isFinish = false;
            OpenCloseFormButton(false);
            ////检测文件是否存在
            if (string.IsNullOrEmpty(textEdit1.Text))
            {
                DevExpress.XtraEditors.XtraMessageBox.Show("请选择bin文件！");
                Fb_SendEvent("bin文件路径不存在，无法执行！");
                OpenCloseFormButton(true);
                return;
            }
            if (string.IsNullOrEmpty(rxPath))
            {
                //DevExpress.XtraEditors.XtraMessageBox.Show("发送配置文件不存在！请联系管理员！");
                Fb_SendEvent("发送协议文件路径不存在，无法执行！");
                OpenCloseFormButton(true);
                return;
            }
            if (string.IsNullOrEmpty(fsysPath))
            {
                Fb_SendEvent("发送系统频率文件路径不存在，无法执行！");
                OpenCloseFormButton(true);
                return;
            }
            //if (null == comBoxPorts.EditValue || string.IsNullOrWhiteSpace(comBoxPorts.EditValue.ToString()))
            if (string.IsNullOrWhiteSpace(Ports))
            {
                DevExpress.XtraEditors.XtraMessageBox.Show("可用端口未选择");
                OpenCloseFormButton(true);
                return;
            }
            if (simpleButton3.Text == "取消")
            {
                
                isSend = false;
                OpenCloseFormButton(true);
                sPortTemp.Close();
                string msg1 = "";
                if (serialPort1.IsOpen)
                {
                    serialPort1.CloseCom(out msg1);
                }
                if (serialPort2.IsOpen)
                {
                    serialPort2.CloseCom(out msg1);
                }
                simpleButton3.Text = "烧写";
                return;
            }
            var isport = sPortTemp.IsOpen;
            if (!isport)
            {
                DevExpress.XtraEditors.XtraMessageBox.Show("请打开端口通讯！");
                OpenCloseFormButton(true);
                return;
            }
            //spi_enable
            simpleButton11_Click(null, null);
            simpleButton7_Click(null, null);
            FileInfo fileInfo = new FileInfo(textEdit1.Text);
            if (fileInfo.Exists)
            {
                if (FlashSize < fileInfo.Length / 1024)
                {
                    DevExpress.XtraEditors.XtraMessageBox.Show("bin文件大于FlashSize");
                    OpenCloseFormButton(true);
                    return;
                }
            }
            ////发送配置文件 寄存器文件写
            RegisterFileWrite(fsysPath);//先发系统频率
            Fb_SendEvent("发系统频率配置文件写入完成！");
            RegisterFileWrite(rxPath);//再发波特率
            Fb_SendEvent("发波特率配置文件写入完成！");
            ////切换通讯
            if (isport)
            {
                sPortTemp.Close(); //关闭以前的
                btnOpenPort.Text = "打开端口";
                //if (null != SendSetXModemClick)
                //{
                //    SendSetXModemClick(true);//关闭串口
                //}
                if (null != OpenPortButtonClick)
                {
                    OpenPortButtonClick(true);
                }
            }


            isSend = true;
            ///新写入的串口通讯
            string msg = string.Empty;
            setSelectedPortConfig(true, true, comBoxAgreement.EditValue.ToString() == "0" ? true : false);
            serialPort1.OpenCom(out msg);
            Fb_SendEvent(msg);
            simpleButton3.Text = "取消";
            //发送bin文件
            Fb_SendEvent("等待烧入中。。。");


            ///配置进度条
            binPBC.Visible = true;
            binPBC.Properties.Minimum = 0;
            binPBC.Properties.Maximum = useBlock1K ? (XmodemData.xmodem1k_C.Count() + 1) : (XmodemData.xmodem_C.Count() + 1);
            binPBC.Properties.Step = 1;
            binPBC.Position = 0;
            binPBC.Properties.ShowTitle = true;
            binPBC.Properties.PercentView = true;
        }
        /// <summary>
        /// 配置串口
        /// </summary>
        /// <param name="isStopBits">Parity 是空校验 true </param>
        /// <param name="issend"> true 使用发送  false 使用接收</param>
        /// <param name="useBlock1K"> true 表示是1kxmodel  false还是 xmodel</param>
        void setSelectedPortConfig(bool isStopBits, bool issend, bool _useBlock1K)
        {
            if (issend)
            {
                serialPort1.ConfigSerialPort = new ConfigComType()
                {
                    //PortName = comBoxPorts.Text,
                    PortName = Ports,
                    BaudRate = 115200,//xmodem波特率定死成115200,需要改3个地方setSelectedPortConfig、ConfigSerialPort、comBoxFSys_EditValueChanged
                    //BaudRate = int.Parse(comBoxBaudRate.Text),
                    //DataBits = int.Parse(comBoxDataBits.Text),
                    DataBits = 8,
                    StopBits = SerialPortHelperLib.StopBits.One,
                    //Parity = isStopBits ? SerialPortHelperLib.Parity.None : (SerialPortHelperLib.Parity)Enum.Parse(typeof(SerialPortHelperLib.Parity), comBoxParity.EditValue.ToString()),
                    Parity = isStopBits ? SerialPortHelperLib.Parity.None : SerialPortHelperLib.Parity.Even,

                };
                //初始化全局变量
                PackageTemp = 0;
                //useBlock1K = comBoxAgreement.EditValue.ToString() == "0" ? true : false;
                useCRC = -1;
                serialPort1.SerialReceviedTimeInterval = 5;
                serialPort1.SerialWriteTimeInterval = 0;
                useBlock1K = _useBlock1K;
            }
            else
            {
                serialPort2.ConfigSerialPort = new ConfigComType()
                {
                    //PortName = comBoxPorts.Text,
                    PortName = Ports,
                    BaudRate = 115200,//xmodem波特率定死成115200,需要改3个地方setSelectedPortConfig、ConfigSerialPort、comBoxFSys_EditValueChanged
                                      //BaudRate = int.Parse(comBoxBaudRate.Text),
                                      //DataBits = int.Parse(comBoxDataBits.Text),
                    DataBits = 8,
                    StopBits = SerialPortHelperLib.StopBits.One,
                    //Parity = isStopBits ? SerialPortHelperLib.Parity.None : (SerialPortHelperLib.Parity)Enum.Parse(typeof(SerialPortHelperLib.Parity), comBoxParity.EditValue.ToString()),
                    Parity = isStopBits ? SerialPortHelperLib.Parity.None : SerialPortHelperLib.Parity.Even,
                };
                //初始化全局变量
                PackageTemp = 0;
                //useBlock1K = comBoxAgreement.EditValue.ToString() == "0" ? true : false;
                useCRC = -1;
                serialPort2.SerialReceviedTimeInterval = 30;
                serialPort2.SerialWriteTimeInterval = 1;
                useBlock1K = _useBlock1K;
                //设置线程传送长度
                if (_useBlock1K)
                {
                    serialPort2.SerialReceviedLengthMax = 1028;
                }
                else
                {
                    serialPort2.SerialReceviedLengthMax = 132;
                }
            }
        }


        #region 寄存器操作

        /// <summary>
        /// 读寄存器地址数据
        /// </summary>
        /// <param name="reg_address"></param>
        /// <returns></returns>
        private string ByteRead(string _reg_address)
        {

            long test_value1 = (long)BaseRegisterMap.SPI_BASE_ADDR;
            uint test_value2 = (uint)SPIRegisterMap.SPI_FUNCTION_SELECT;
            uint FUNCT_SEL_ADDR = (uint)(test_value1 + test_value2);

            fb = new FlashBase(sPortTemp);
            fb.SendEvent += Fb_SendEvent;
            fb.SendRegDataARM(0x1, FUNCT_SEL_ADDR, 0, sPortTemp);

            uint reg_address = Convert.ToUInt32(_reg_address, 16);
            uint recvdata = 0;
            fb.ReadRegDataARM(0x31, reg_address, ref recvdata, sPortTemp);
            return Convert.ToString(recvdata, 16).ToUpper();
        }

        public static UInt32 addr;//全局变量

        /// <summary>
        /// 寄存器文件写
        /// </summary>
        /// <param name="path"></param>
        private void RegisterFileWrite(string path)
        {
            long test_value1 = (long)BaseRegisterMap.SPI_BASE_ADDR;
            uint test_value2 = (uint)SPIRegisterMap.SPI_FUNCTION_SELECT;
            uint FUNCT_SEL_ADDR = (uint)(test_value1 + test_value2);
            fb = new FlashBase(sPortTemp);
            fb.SendEvent += Fb_SendEvent;
            try
            {
                string txt_str = String.Empty;
                string[] ss;
                UInt32 reg_address;
                UInt32 reg_data;
                UInt32 Value;
                StreamReader f2 = new StreamReader(path, System.Text.Encoding.GetEncoding("gb2312"));//gb2312编码，为制定文件名初始化

                while (f2.Peek() > -1)
                {
                    txt_str = f2.ReadLine().Trim();
                    ss = txt_str.Split(',');
                    if (ss.Length >= 2)
                    {
                        
                        if (ss[0].Trim() == "0xfffd")
                        {

                            addr = (Convert.ToUInt32(ss[1].Trim(), 16) & 0xff) << 24;
                        }
                        else if (ss[0].Trim() == "0xfffe")
                        {

                            //addr = 0x80000000;
                            addr += (Convert.ToUInt32(ss[1].Trim(), 16) & 0xff) << 16;
                        }
                        else if (ss[0].Trim() == "0xffff")
                        {

                            uint t;
                            t = (Convert.ToUInt32(ss[1].Trim(), 16) & 0xff);
                            Thread.Sleep(1000);
                        }
                        else if (ss[0].Trim() == "0xfff3")
                        {

                            UInt16 chip_id;
                            reg_address = 0x80500010;
                            reg_data = 0;
                            fb.ReadRegDataARM(0x11, reg_address, ref reg_data, sPortTemp);
                            chip_id = (UInt16)(reg_data >> 16);
                            if (chip_id != Convert.ToUInt32(ss[1].Trim(), 16))
                            {
                                f2.Close();//释放系统资源
                                f2.Dispose();
                                Fb_SendEvent("Chip ID don't match, Write stopped!");
                                break;
                            }

                        }
                        else
                        {

                            reg_address = addr + (Convert.ToUInt32(ss[0].Trim(), 16) & 0xffff);
                            reg_data = Convert.ToUInt32(ss[1].Trim(), 16);
                            int byte_sel = (int)(reg_address) & 0x3;
                            byte_sel = byte_sel * 8;

                            //int reg_data = Convert.ToUInt32(txtBoxRegData.Text, 16);
                            reg_data = reg_data & 0xff;
                            reg_data = reg_data << byte_sel;
                            Value = fb.SendRegDataARM(0x21, reg_address, reg_data, sPortTemp);

                            if (Value != 0x21)
                            {
                                f2.Close();//释放系统资源
                                f2.Dispose();
                                //Fb_SendEvent("error");
                                break;
                            }
                        }
                    }

                }

                Application.DoEvents();
                f2.Close();//释放系统资源
                f2.Dispose();

            }
            catch (Exception ex)
            {
                Fb_SendEvent(ex.Message.ToString());
            }

        }

        #endregion

        double receiveTempCout = 0;
        private void simpleButton4_Click(object sender, EventArgs e)
        {
            try
            {
                if (sPortTemp.IsOpen)
                {
                    CalculationCrystalOscillator();
                }
                isFinish = false;
                OpenCloseFormButton(false);
                //if (null == comBoxPorts.EditValue || string.IsNullOrWhiteSpace(comBoxPorts.EditValue.ToString()))
                if (string.IsNullOrWhiteSpace(Ports))
                {
                    DevExpress.XtraEditors.XtraMessageBox.Show("可用端口未选择");
                    OpenCloseFormButton(true);
                    return;
                }
                if (string.IsNullOrEmpty(textEdit2.Text))
                {
                    DevExpress.XtraEditors.XtraMessageBox.Show("保存路劲未选择");
                    OpenCloseFormButton(true);
                    return;
                }
                if (string.IsNullOrEmpty(textEdit3.Text) || textEdit3.Text == "0000")
                {
                    DevExpress.XtraEditors.XtraMessageBox.Show("请修改长度！！！");
                    OpenCloseFormButton(true);
                    return;
                }

                #region 修改系统频率为晶振频率  
                
                if(null != SendChangeSysClk)
                {
                    SendChangeSysClk();
                }

                #endregion

                if (string.IsNullOrEmpty(txPath))
                {
                    //DevExpress.XtraEditors.XtraMessageBox.Show("发送配置文件不存在！请联系管理员！");
                    Fb_SendEvent("发送协议路径不存在，无法执行！");
                    OpenCloseFormButton(true);
                    return;
                }
                if (string.IsNullOrEmpty(fsysPath))
                {
                    Fb_SendEvent("发送系统频率路径不存在，无法执行！");
                    OpenCloseFormButton(true);
                    return;
                }
                if (simpleButton4.Text == "取消")
                {
                    isSend = false;
                    OpenCloseFormButton(true);
                    return;
                }
                //全局变量
                useBlock1K = comBoxAgreement.EditValue.ToString() == "0" ? true : false;
                receiveList = new List<List<byte>>();
                //获取文件长度 初始化接收变量
                var tempVal = Convert.ToInt32(textEdit3.Text, 16);
                receiveTempCout = 0;
                if (useBlock1K)
                {
                    receiveTempCout = Math.Ceiling(tempVal / 1024.0);
                }
                else
                {
                    receiveTempCout = Math.Ceiling(tempVal / 128.0);
                }

                var isport = sPortTemp.IsOpen;
                if (!isport)
                {
                    DevExpress.XtraEditors.XtraMessageBox.Show("请打开端口通讯！");
                    OpenCloseFormButton(true);
                    return;
                }
                Thread.Sleep(1000);
                ///初始化
                rxtemplists = new List<XmodemRequest>();
                ////发送配置文件 寄存器文件写
                RegisterFileWrite(fsysPath);//先发系统频率
                Fb_SendEvent("发系统频率配置文件写入完成！");
                RegisterFileWrite(txPath);//再发波特率
                Fb_SendEvent("发波特率配置文件写入完成！");

                //切换通讯
                if (isport)
                {
                    sPortTemp.Close(); //关闭以前的
                    btnOpenPort.Text = "打开端口";
                    //if (null != SendSetXModemClick)
                    //{
                    //    SendSetXModemClick(true);//关闭串口
                    //}
                    if (null != OpenPortButtonClick)
                    {
                        OpenPortButtonClick(true);
                    }
                }
                tempSize = 0;//初始
                tempReceived = -1;//初始序号
                rxtemplists = new List<XmodemRequest>();
                //templists = new List<List<byte>>(); ////初始化数据
                isSend = true;
                ///新写入的串口通讯
                string msg = string.Empty;
                setSelectedPortConfig(true, false, comBoxAgreement.EditValue.ToString() == "0" ? true : false);
                serialPort2.OpenCom(out msg);
                Fb_SendEvent(msg);
                simpleButton4.Text = "取消";
                Fb_SendEvent("等待导出中。。。");
                //发送第一波数据
                serialPort2.Write(new byte[] { 0x15 });

                ///配置进度条
                binPBC.Visible = true;
                binPBC.Properties.Minimum = 0;
                binPBC.Properties.Maximum = (int)receiveTempCout + 10;
                binPBC.Properties.Step = 1;
                binPBC.Position = 0;
                binPBC.Properties.ShowTitle = true;
                binPBC.Properties.PercentView = true;

            }
            catch (Exception ex)
            {
                string msg = string.Empty;
                serialPort2.CloseCom(out msg);
                DevExpress.XtraEditors.XtraMessageBox.Show(string.Format("{0}{2}", ex.Message.ToString(), msg));
                OpenCloseFormButton(true);
            }
        }

        private void textEdit3_EditValueChanged(object sender, EventArgs e)
        {
            var sysStr = textEdit3.Text.PadLeft(8, '0').ToList();
            List<string> listbin = new List<string>();
            for (int i = 0; i < sysStr.Count;)
            {
                listbin.Add(string.Format("{0}{1}", sysStr[i], sysStr[i + 1]));
                i += 2;
            }

            SetTxRxPath();
        }
        bool iscomBox = false;
        private void comBoxAgreement_EditValueChanged(object sender, EventArgs e)
        {
            iscomBox = true;
            if (comBoxAgreement.EditValue.ToString() == "0") //表示1kxmodel
            {
                tx_txt.Text = ParaList.Tx_flash_1k.First(c => c.PKey == "0x133e").PValue.Replace("0x", "");
                rx_txt.Text = ParaList.Rx_flash_1k.First(c => c.PKey == "0x1340").PValue.Replace("0x", "");
            }
            else
            {
                tx_txt.Text = ParaList.Tx_flash.First(c => c.PKey == "0x133e").PValue.Replace("0x", "");
                rx_txt.Text = ParaList.Rx_flash.First(c => c.PKey == "0x1340").PValue.Replace("0x", "");
            }
            SetTxRxPath();
            iscomBox = false;
        }

        private void comBoxFSys_EditValueChanged(object sender, EventArgs e)
        {
            double number;
            if (!double.TryParse(FSystxt.Text.ToString(), out number)|| !double.TryParse(FArmtxt.Text.ToString(), out number))
            {
                return;
            }
            //生成系统频率文件
            //判断是否存在FSys如果不存在就新建一个
            if (!File.Exists(string.Format("{0}\\Lib\\FSys.txt", Application.StartupPath)))
            {
                File.AppendAllText(string.Format("{0}\\Lib\\FSys.txt", Application.StartupPath), "");
            }
            fsysPath = string.Format("{0}\\Lib\\FSys.txt", Application.StartupPath);
            //获取系统频率
            //获取长度
            var comBxBaudRate = "115200";//xmodem波特率定死成115200,需要改3个地方setSelectedPortConfig、ConfigSerialPort、comBoxFSys_EditValueChanged                    
            //var comBxBaudRate = comBoxBaudRate.Text.ToString();
            var comBxFSys = FSystxt.Text.ToString();
            var comBxFArm = FArmtxt.Text.ToString();
            //计算长度
            //计算系统频率
            var list = SYSHelper.GetFSys(double.Parse(comBxFArm), 8);
            var list2 = SYSHelper.GetFsys_Bps(double.Parse(comBxBaudRate), double.Parse(comBxFArm), 4);
            //写入静态list集合中
            SYSHelper.SetFsysBps(list);
            SYSHelper.SetFsysSystem(list2);
            //获取生成字符串
            var str = SYSHelper.CreateFsys();
            //写入文件
            File.WriteAllText(fsysPath, str);
            //此处是为了全局Bin系统文件
            
            //判断上级文件夹是否存在
            if (!Directory.Exists(string.Format("{0}\\Lib\\xc151_Bin", Application.StartupPath)))
            {
                Directory.CreateDirectory(string.Format("{0}\\Lib\\xc151_Bin", Application.StartupPath));
            }
            //判断是否存在FSys如果不存在就新建一个
            if (!File.Exists(string.Format("{0}\\Lib\\xc151_Bin\\FSys.txt", Application.StartupPath)))
            {
                File.AppendAllText(string.Format("{0}\\Lib\\xc151_Bin\\FSys.txt", Application.StartupPath), "");
            }
            fsysPath = string.Format("{0}\\Lib\\xc151_Bin\\FSys.txt", Application.StartupPath);
            File.WriteAllText(fsysPath, str);

        }
        /// <summary>
        /// 晶振修改
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void jzTxt_EditValueChanging(object sender, DevExpress.XtraEditors.Controls.ChangingEventArgs e)
        {
            if (string.IsNullOrEmpty(jzTxt.Text))
                return;
            try
            {
                //获取Configuration对象
                Configuration config = System.Configuration.ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                config.AppSettings.Settings["PAD_CLK"].Value = jzTxt.Text;
                RegisterSystemHelp.jzTemp = jzTxt.Text;
                //CalculationCrystalOscillator(); 
                config.Save(ConfigurationSaveMode.Modified);
                System.Configuration.ConfigurationManager.RefreshSection("appSettings");
            }
            catch
            {
                return;
            }
        }

        private void simpleButton11_Click(object sender, EventArgs e)
        {
            var isport = sPortTemp.IsOpen;
            if (!isport)
            {
                DevExpress.XtraEditors.XtraMessageBox.Show("请打开端口通讯！");
                return;
            }
            ErasePrecent.EditValue = 0;
            //long test_value1 = (long)BaseRegisterMap.SPI_BASE_ADDR;
            //uint test_value2 = (uint)SPIRegisterMap.SPI_FUNCTION_SELECT;
            //uint FUNCT_SEL_ADDR = (uint)(test_value1 + test_value2);

            ////Fb_SendEvent(string.Format("SPI使能发送注册表数据...\r\n"));
            //fb.SendRegDataARM(0x1, FUNCT_SEL_ADDR, 0, sPortTemp);
            //Fb_SendEvent(string.Format("SPI使能发送注册表数据完成\r\n"));
            //fb.SendEvent += Fb_SendEvent;
            //Thread.Sleep(200);
            //Fb_SendEvent(string.Format("SPI使能读取注册表数据...\r\n"));
            //fb.ReadRegData(0x31, 0x80500200, ref recdata, sPortTemp);// 805000F1  0x55
            Fb_SendEvent("SPI使能执行...\r\n");
            FlashBase fb = new FlashBase(sPortTemp);
            var recdata = fb.ReadRegisterARM(0x31, 0x805000F1, sPortTemp);// 805000F1  0x55
            Fb_SendEvent(string.Format("SPI使能读取注册表数据完成\r\n"));
            recdata = (uint)recdata |0x00000055U;

            //Fb_SendEvent(string.Format("SPI使能发送注册表数据...\r\n"));
            fb.WriteRegisterARM(0x21, 0x805000F1, recdata, sPortTemp);
            Fb_SendEvent(string.Format("SPI使能发送注册表数据完成\r\n"));
            Fb_SendEvent(string.Format("SPI使能执行完成\r\n"));
        }





        public void ClosePort() {
            if (sPortTemp.IsOpen)
            {
                sPortTemp.Close();
            }
        }

        public void OpenPort(SerialPort sPortTemp1 ,string _BaudRate ,string _Ports) {
            sPortTemp = sPortTemp1;
            this.BaudRate = _BaudRate;
            this.Ports = _Ports;
            //comBoxBaudRate.Text = BaudRate;
            //comBoxPorts.Text = Ports;
            #region 获取flash写保护状态
            if (sPortTemp1.IsOpen)
            {
                //var byteTemp = SerialSend.ReadRegister(0x31, Convert.ToUInt32("80500137", 16), sPortTemp); 
                //if (byteTemp == 0x0 || byteTemp == 0xff)
                //{
                //    Fb_SendEvent(string.Format("串口通讯失败：{0}", byteTemp));
                //    sPortTemp1.Close();
                //    return;
                //}
                //spi使能
                //simpleButton11_Click(null, null);
                //if ((ReadStatusFlash() & 0x1c) == 0x1c)//是否处于写保护状态
                //{//是                   
                //    simpleButton1.Text = "解除写保护";
                //}
                //else
                //{//否                   
                //    simpleButton1.Text = "开启写保护";
                //}
            } 
            #endregion
            else
            {
                try
                {
                    sPortTemp.PortName = Ports;
                    sPortTemp.BaudRate = int.Parse(BaudRate);
                    sPortTemp.DataBits = 8;
                    //sPortTemp.PortName = comBoxPorts.Text;
                    //sPortTemp.BaudRate = int.Parse(comBoxBaudRate.Text);
                    //sPortTemp.DataBits = int.Parse(comBoxDataBits.Text);
                    sPortTemp.StopBits = System.IO.Ports.StopBits.One;
                    sPortTemp.Parity = (System.IO.Ports.Parity)Enum.Parse(typeof(System.IO.Ports.Parity), comBoxParity.EditValue.ToString());
                    sPortTemp.DtrEnable = true;
                    sPortTemp.RtsEnable = true;
                    sPortTemp.Open();
                    Fb_SendEvent("串口通信执行成功！");
                    //添加验证串口通讯
                    //var byteTemp = ByteRead("80500137");
                    //if (byteTemp == "0" || byteTemp.ToUpper() == "FF")
                    var byteTemp = SerialSend.ReadRegister(Convert.ToUInt32("80500137", 16), sPortTemp);
                    if (byteTemp == 0x0 || byteTemp == 0xff)
                    {
                        Fb_SendEvent(string.Format("串口通讯失败：{0}", byteTemp));
                        sPortTemp.Close();
                        return;
                    }  
                }
                catch (Exception ex)
                {

                    Fb_SendEvent(string.Format("串口通讯失败：{0}", ex.Message.ToString())); return;
                }

              

            }
            if (sPortTemp.IsOpen)
            {
                 //CalculationCrystalOscillator(); 
            }
           
            btnOpenPort.Text = sPortTemp.IsOpen ? "关闭串口" : "打开串口";
        }

        private void btnOpenPort_Click(object sender, EventArgs e)
        {
            try
            {
                Fb_SendEvent("串口通信开始!");
                if (null == comBoxPorts.EditValue || string.IsNullOrWhiteSpace(comBoxPorts.EditValue.ToString()))
                {
                    DevExpress.XtraEditors.XtraMessageBox.Show("可用端口未选择");
                    return;
                }
                OpenCloseSPort();
            }
            catch (Exception ex)
            {
                Fb_SendEvent(string.Format("串口通信失败:{0}",ex.Message.ToString()));            

            }

        }

        void OpenCloseSPort()
        {
            if (sPortTemp.IsOpen)
            {
                sPortTemp.Close();
                Fb_SendEvent("串口通信关闭串口！");
            }
            else
            {
                try
                {
                    sPortTemp.PortName = Ports;
                    sPortTemp.BaudRate = int.Parse(BaudRate);
                    sPortTemp.DataBits = 8;
                    //sPortTemp.PortName = comBoxPorts.Text;
                    //sPortTemp.BaudRate = int.Parse(comBoxBaudRate.Text);
                    //sPortTemp.DataBits = int.Parse(comBoxDataBits.Text);
                    sPortTemp.StopBits = System.IO.Ports.StopBits.One;
                    sPortTemp.Parity = (System.IO.Ports.Parity)Enum.Parse(typeof(System.IO.Ports.Parity), comBoxParity.EditValue.ToString());
                    sPortTemp.DtrEnable = true;
                    sPortTemp.RtsEnable = true;
                    sPortTemp.Open();
                    Fb_SendEvent("串口通信执行成功！");
                    //添加验证串口通讯
                    //var byteTemp = ByteRead("80500137");
                    //if (byteTemp == "0" || byteTemp.ToUpper() == "FF")
                    var byteTemp = SerialSend.ReadRegister(Convert.ToUInt32("80500137", 16), sPortTemp);
                    if (byteTemp == 0x0 || byteTemp == 0xff)
                    {
                        Fb_SendEvent(string.Format("串口通讯失败：{0}", byteTemp));
                        sPortTemp.Close();
                        return;
                    }
                }
                catch (Exception ex)
                {

                    Fb_SendEvent(string.Format("串口通讯失败：{0}", ex.Message.ToString())); return;
                }
              
               //CalculationCrystalOscillator(); 
              
            }
            btnOpenPort.Text = sPortTemp.IsOpen ? "关闭串口" : "打开串口";

        }

        public void CalculationCrystalOscillator() {
            FSystxt.Text = string.Empty;

            FArmtxt.Text = string.Empty;
            if (sPortTemp.IsOpen && !string.IsNullOrEmpty(jzTxt.Text))
            {
                RegisterSystemHelp.jzTemp = jzTxt.Text;
                List<string> list = new List<string>();
                foreach (var item in RegisterSystemHelp.SysList)
                {
                    list.Add(SerialSend.ReadRegister( Convert.ToUInt32(item, 16), sPortTemp).ToString("X2"));
                }
                var dou = RegisterSystemHelp.sys_clk(list[0], list[1], list[2], list[3], list[4], list[5]);
                list = new List<string>();
                foreach (var item in RegisterSystemHelp.ArmList)
                {
                    list.Add(SerialSend.ReadRegister( Convert.ToUInt32(item, 16), sPortTemp).ToString("X2"));
                }
                var dou2 = RegisterSystemHelp.arm_clk(list[0], list[1], list[2], list[3], list[4], list[5]);

                FSystxt.Text = dou.ToString();

                FArmtxt.Text = dou2.ToString();
                //判断是否为负数，如果是就重复调用最多五次该方法进行刷新
                if ((dou < 0 || dou2 < 0) && FSysFArmsum < 6)
                {
                    FSysFArmsum++;
                    CalculationCrystalOscillator();
                }
                else if ((dou < 0 || dou2 < 0) && FSysFArmsum > 5)
                {
                    FSysFArmsum = 0;
                    DevExpress.XtraEditors.XtraMessageBox.Show("请检查端口通讯！");
                }
                else
                {
                    FSysFArmsum = 0;
                }
                //var listP = XModem.library.Port.GetFSYS();
                //var idx = 0;
                //for (int i = 0; i < listP.Count; i++)
                //{
                //    if (listP[i].ValueMember == dou.ToString())
                //    {
                //        idx = i;
                //        break;
                //    }
                //    else {
                //        idx = -1;
                //    }
                //}
                //if (idx == -1 && dou >0)
                //{
                //    listP.Add(new TreeListValue() { ValueMember = $"{dou}", DisplayMember = $"{dou}" });
                //    idx = listP.Count-1;
                //}
                //for (int i = 0; i < 27; i++)
                //{
                //    listP.Add(new TreeListValue() { ValueMember = $"{i}", DisplayMember = $"{i}" });
                //}
                //comBoxFSys.Properties.DataSource = listP;
                //comBoxFSys.ItemIndex = idx;
            }
        }
        /// <summary>
        /// 开启关闭false按钮点击
        /// </summary>
        /// <param name="isbool"></param>
        void OpenCloseFormButton(bool isbool)
        {
            btnFlashRead.Enabled = isbool;
            btnFlashWrite.Enabled = isbool;
            btnFlashErase.Enabled = isbool;
            btnReadID.Enabled = isbool;
            btnFullChipErase.Enabled = isbool;
            simpleButton11.Enabled = isbool;
            btnFlashWrite_File.Enabled = isbool;
            btnReadFlashToTxtFile.Enabled = isbool;
            simpleButton1.Enabled = isbool;
            //btnReadFlashToBinFile.Enabled = isbool;
            //btnDownloadBin.Enabled = isbool;
        }

        private void btnFlashRead_Click(object sender, EventArgs e)
        {
            if (IsUsbOpen)
            {
                uint pVule = 0x0;
                bool isbool;
                if (IntPtr.Size == 8)
                {
                    isbool = XChipUSB.UsbFlashRead64(Convert.ToUInt32(txtBoxFlashAddress.Text, 16), ref pVule);
                }
                else
                {
                    isbool = XChipUSB.UsbFlashRead86(Convert.ToUInt32(txtBoxFlashAddress.Text, 16), ref pVule);
                }
                if (isbool)
                {
                    txtBoxFlashData.Text = pVule.ToString("X2");
                }

                return;
            }
            

            if (!sPortTemp.IsOpen)
            {
                DevExpress.XtraEditors.XtraMessageBox.Show("串口没有打开");
                return;
            }
            if (!Regex.Match(txtBoxFlashAddress.Text, @"^[A-Za-z0-9]+$").Success)
            {
                return;
            }

            ErasePrecent.EditValue = 0;
            //Fb_SendEvent("Flash操作->读 开始执行\r\n");

            //long test_value1 = (long)BaseRegisterMap.SPI_BASE_ADDR;

            //uint test_value2 = (uint)SPIRegisterMap.SPI_FUNCTION_SELECT;
            //uint FUNCT_SEL_ADDR = (uint)(test_value1 + test_value2);

            //test_value2 = (uint)SPIRegisterMap.SPI_CONTROL;
            //uint CONTROL_ADDR = (uint)(test_value1 + test_value2);

            //test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_CONTROL;
            //uint SHIFT_ADDR = (uint)(test_value1 + test_value2);

            //test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_TXD0;
            //uint TXD0_ADDR = (uint)(test_value1 + test_value2);

            //test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_TXD1;
            //uint TXD1_ADDR = (uint)(test_value1 + test_value2);


            //test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_RXD0;
            //uint RXD0_ADDR = (uint)(test_value1 + test_value2);

            //test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_RXD1;
            //uint RXD1_ADDR = (uint)(test_value1 + test_value2);


            //uint flash_address = Convert.ToUInt32(txtBoxFlashAddress.Text, 16);

            //uint spi_shift_cnt;
            //uint spi_rxvld_cnt;
            //uint senddata;
            //uint recvdata = 0;
            //uint op_code = 0x03;

            //FlashBase fb = new FlashBase(sPortTemp);
            //fb.SendRegDataARM(0x1, FUNCT_SEL_ADDR, 0x1, sPortTemp);
            //fb.SendEvent += Fb_SendEvent;
            //Thread.Sleep(200);
            //senddata = (((flash_address & 0xff) << 24) + ((flash_address & 0xff00) << 8) + ((flash_address & 0xff0000) >> 8) + op_code);
            //fb.SendRegDataARM(0x1, TXD0_ADDR, senddata, sPortTemp);
            //Thread.Sleep(200);
            //spi_shift_cnt = 64;
            //spi_rxvld_cnt = 32;
            //senddata = (3 << 16) + (spi_rxvld_cnt << 8) + (spi_shift_cnt << 0);
            //fb.SendRegDataARM(0x1, SHIFT_ADDR, senddata, sPortTemp);
            //Thread.Sleep(200);

            //fb.ReadRegDataARM(0x11, RXD0_ADDR, ref recvdata, sPortTemp);

            //this.txtBoxFlashData.Text = Convert.ToString(recvdata, 16).ToUpper();
            //Fb_SendEvent("Flash操作->读 执行完成\r\n");

            this.txtBoxFlashData.Text = FlashRead(Convert.ToUInt32(txtBoxFlashAddress.Text, 16));
        }



        private string FlashRead(uint flash_address) {
            Fb_SendEvent("Flash操作->读 开始执行\r\n");

            long test_value1 = (long)BaseRegisterMap.SPI_BASE_ADDR;

            uint test_value2 = (uint)SPIRegisterMap.SPI_FUNCTION_SELECT;
            uint FUNCT_SEL_ADDR = (uint)(test_value1 + test_value2);

            test_value2 = (uint)SPIRegisterMap.SPI_CONTROL;
            uint CONTROL_ADDR = (uint)(test_value1 + test_value2);

            test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_CONTROL;
            uint SHIFT_ADDR = (uint)(test_value1 + test_value2);

            test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_TXD0;
            uint TXD0_ADDR = (uint)(test_value1 + test_value2);

            test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_TXD1;
            uint TXD1_ADDR = (uint)(test_value1 + test_value2);


            test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_RXD0;
            uint RXD0_ADDR = (uint)(test_value1 + test_value2);

            test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_RXD1;
            uint RXD1_ADDR = (uint)(test_value1 + test_value2);


            //uint flash_address = Convert.ToUInt32(txtBoxFlashAddress.Text, 16);

            uint spi_shift_cnt;
            uint spi_rxvld_cnt;
            uint senddata;
            uint recvdata = 0;
            uint op_code = 0x03;

            FlashBase fb = new FlashBase(sPortTemp);
            fb.SendRegDataARM(0x1, FUNCT_SEL_ADDR, 0x1, sPortTemp);
            fb.SendEvent += Fb_SendEvent;
            Thread.Sleep(100);
            senddata = (((flash_address & 0xff) << 24) + ((flash_address & 0xff00) << 8) + ((flash_address & 0xff0000) >> 8) + op_code);
            fb.SendRegDataARM(0x1, TXD0_ADDR, senddata, sPortTemp);
            Thread.Sleep(100);
            spi_shift_cnt = 64;
            spi_rxvld_cnt = 32;
            senddata = (3 << 16) + (spi_rxvld_cnt << 8) + (spi_shift_cnt << 0);
            fb.SendRegDataARM(0x1, SHIFT_ADDR, senddata, sPortTemp);
            Thread.Sleep(100);

            fb.ReadRegDataARM(0x11, RXD0_ADDR, ref recvdata, sPortTemp);
            Fb_SendEvent("Flash操作->读 执行完成\r\n");
            return Convert.ToString(recvdata, 16).ToUpper();
          
        }


        private void btnFlashWrite_Click(object sender, EventArgs e)
        {
            if (IsUsbOpen)
            {
                bool isbool;
                if (IntPtr.Size == 8)
                {
                    isbool = XChipUSB.UsbFlashWrite64(Convert.ToUInt32(txtBoxFlashAddress.Text, 16), Convert.ToUInt32(txtBoxFlashData.Text, 16));
                }
                else
                {
                    isbool = XChipUSB.UsbFlashWrite86(Convert.ToUInt32(txtBoxFlashAddress.Text, 16), Convert.ToUInt32(txtBoxFlashData.Text, 16));
                }
                if (isbool)
                {
                    //txtBoxFlashData.Text = pVule.ToString("X2");
                }

                return;
            }


            if (!sPortTemp.IsOpen)
            {
                DevExpress.XtraEditors.XtraMessageBox.Show("串口没有打开");
                return;
            }
            if (!Regex.Match(txtBoxFlashAddress.Text, @"^[A-Za-z0-9]+$").Success && !Regex.Match(txtBoxFlashData.Text, @"^[A-Za-z0-9]+$").Success)
            {
                return;
            }
            ErasePrecent.EditValue = 0;
            //Fb_SendEvent("Flash操作->写 执行开始\r\n");

            //long test_value1 = (long)BaseRegisterMap.SPI_BASE_ADDR;

            //uint test_value2 = (uint)SPIRegisterMap.SPI_FUNCTION_SELECT;
            //uint FUNCT_SEL_ADDR = (uint)(test_value1 + test_value2);

            //test_value2 = (uint)SPIRegisterMap.SPI_CONTROL;
            //uint CONTROL_ADDR = (uint)(test_value1 + test_value2);

            //test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_CONTROL;
            //uint SHIFT_ADDR = (uint)(test_value1 + test_value2);

            //test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_TXD0;
            //uint TXD0_ADDR = (uint)(test_value1 + test_value2);

            //test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_TXD1;
            //uint TXD1_ADDR = (uint)(test_value1 + test_value2);


            //test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_RXD0;
            //uint RXD0_ADDR = (uint)(test_value1 + test_value2);

            //test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_RXD1;
            //uint RXD1_ADDR = (uint)(test_value1 + test_value2);

            //uint flash_address = Convert.ToUInt32(txtBoxFlashAddress.Text, 16);
            //uint flash_data = Convert.ToUInt32(txtBoxFlashData.Text, 16);

            //uint spi_shift_cnt;
            //uint spi_rxvld_cnt;
            //uint senddata;
            //uint recvdata = 0;

            ////spi mode
            //FlashBase fb = new FlashBase(sPortTemp);
            //fb.SendRegDataARM(0x1, FUNCT_SEL_ADDR, 0x1, sPortTemp);
            //fb.SendEvent += Fb_SendEvent;
            //Thread.Sleep(200);
            ////spi cs 片选
            //uint spi_cs = 1;
            //fb.ReadRegDataARM(0x11, CONTROL_ADDR, ref recvdata, sPortTemp);
            //senddata = recvdata & 0xffff3cff;
            //senddata = senddata + (spi_cs << 8);
            //fb.SendRegDataARM(0x1, CONTROL_ADDR, senddata, sPortTemp);
            //recvdata = fb.FlashReadStatus(sPortTemp);
            //fb.FlashWriteEnable(sPortTemp);
            //recvdata = fb.FlashReadStatus(sPortTemp);
            ////unprotected
            //senddata = (((flash_address & 0xff) << 24) + ((flash_address & 0xff00) << 8) + ((flash_address & 0xff0000) >> 8) + 0x39);
            //fb.SendRegDataARM(0x1, TXD0_ADDR, senddata, sPortTemp);
            ////SHIFT_CONTROL
            //spi_shift_cnt = 32;
            //spi_rxvld_cnt = 0;
            //senddata = (3 << 16) + (spi_rxvld_cnt << 8) + (spi_shift_cnt << 0);
            //fb.SendRegDataARM(0x1, SHIFT_ADDR, senddata, sPortTemp);
            //Thread.Sleep(200);
            //recvdata = fb.FlashReadStatus(sPortTemp);
            //fb.FlashWriteEnable(sPortTemp);
            //recvdata = fb.FlashReadStatus(sPortTemp);
            ////TXD0
            //senddata = (((flash_address & 0xff) << 24) + ((flash_address & 0xff00) << 8) + ((flash_address & 0xff0000) >> 8) + 0x02);
            //fb.SendRegDataARM(0x1, TXD0_ADDR, senddata, sPortTemp);
            ////TXD1
            //senddata = flash_data;
            //fb.SendRegDataARM(0x1, TXD1_ADDR, senddata, sPortTemp);
            ////SHIFT_CONTROL
            //spi_shift_cnt = 64;
            //spi_rxvld_cnt = 0;
            //senddata = (3 << 16) + (spi_rxvld_cnt << 8) + (spi_shift_cnt << 0);
            //fb.SendRegDataARM(0x1, SHIFT_ADDR, senddata, sPortTemp);
            //Thread.Sleep(200);
            //Fb_SendEvent("Flash操作->写 执行成功\r\n");

            FlashWrite(Convert.ToUInt32(txtBoxFlashAddress.Text, 16), Convert.ToUInt32(txtBoxFlashData.Text, 16));
        }

        private void FlashWrite(uint flash_address, uint flash_data)
        {
            Fb_SendEvent("Flash操作->写 执行开始\r\n");

            long test_value1 = (long)BaseRegisterMap.SPI_BASE_ADDR;

            uint test_value2 = (uint)SPIRegisterMap.SPI_FUNCTION_SELECT;
            uint FUNCT_SEL_ADDR = (uint)(test_value1 + test_value2);

            test_value2 = (uint)SPIRegisterMap.SPI_CONTROL;
            uint CONTROL_ADDR = (uint)(test_value1 + test_value2);

            test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_CONTROL;
            uint SHIFT_ADDR = (uint)(test_value1 + test_value2);

            test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_TXD0;
            uint TXD0_ADDR = (uint)(test_value1 + test_value2);

            test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_TXD1;
            uint TXD1_ADDR = (uint)(test_value1 + test_value2);


            test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_RXD0;
            uint RXD0_ADDR = (uint)(test_value1 + test_value2);

            test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_RXD1;
            uint RXD1_ADDR = (uint)(test_value1 + test_value2);

            //uint flash_address = Convert.ToUInt32(txtBoxFlashAddress.Text, 16);
            //uint flash_data = Convert.ToUInt32(txtBoxFlashData.Text, 16);

            uint spi_shift_cnt;
            uint spi_rxvld_cnt;
            uint senddata;
            uint recvdata = 0;

            //spi mode
            FlashBase fb = new FlashBase(sPortTemp);
            fb.SendRegDataARM(0x1, FUNCT_SEL_ADDR, 0x1, sPortTemp);
            fb.SendEvent += Fb_SendEvent;
            Thread.Sleep(200);
            //spi cs 片选
            uint spi_cs = 1;
            fb.ReadRegDataARM(0x11, CONTROL_ADDR, ref recvdata, sPortTemp);
            senddata = recvdata & 0xffff3cff;
            senddata = senddata + (spi_cs << 8);
            fb.SendRegDataARM(0x1, CONTROL_ADDR, senddata, sPortTemp);
            recvdata = fb.FlashReadStatus(sPortTemp);
            fb.FlashWriteEnable(sPortTemp);
            recvdata = fb.FlashReadStatus(sPortTemp);
            //unprotected
            senddata = (((flash_address & 0xff) << 24) + ((flash_address & 0xff00) << 8) + ((flash_address & 0xff0000) >> 8) + 0x39);
            fb.SendRegDataARM(0x1, TXD0_ADDR, senddata, sPortTemp);
            //SHIFT_CONTROL
            spi_shift_cnt = 32;
            spi_rxvld_cnt = 0;
            senddata = (3 << 16) + (spi_rxvld_cnt << 8) + (spi_shift_cnt << 0);
            fb.SendRegDataARM(0x1, SHIFT_ADDR, senddata, sPortTemp);
            Thread.Sleep(200);
            recvdata = fb.FlashReadStatus(sPortTemp);
            fb.FlashWriteEnable(sPortTemp);
            recvdata = fb.FlashReadStatus(sPortTemp);
            //TXD0
            senddata = (((flash_address & 0xff) << 24) + ((flash_address & 0xff00) << 8) + ((flash_address & 0xff0000) >> 8) + 0x02);
            fb.SendRegDataARM(0x1, TXD0_ADDR, senddata, sPortTemp);
            //TXD1
            senddata = flash_data;
            fb.SendRegDataARM(0x1, TXD1_ADDR, senddata, sPortTemp);
            //SHIFT_CONTROL
            spi_shift_cnt = 64;
            spi_rxvld_cnt = 0;
            senddata = (3 << 16) + (spi_rxvld_cnt << 8) + (spi_shift_cnt << 0);
            fb.SendRegDataARM(0x1, SHIFT_ADDR, senddata, sPortTemp);
            Thread.Sleep(200);
            Fb_SendEvent("Flash操作->写 执行成功\r\n");
        }

        private void btnFlashErase_Click(object sender, EventArgs e)
        {
            if (!sPortTemp.IsOpen)
            {
                DevExpress.XtraEditors.XtraMessageBox.Show("串口没有打开");
                return;
            }
            if (!Regex.Match(txtBoxFlashAddress.Text, @"^[A-Za-z0-9]+$").Success)
            {
                return;
            }
            ErasePrecent.EditValue = 0;
            Fb_SendEvent("Flash操作->擦除 执行开始\r\n");
            long test_value1 = (long)BaseRegisterMap.SPI_BASE_ADDR;

            uint test_value2 = (uint)SPIRegisterMap.SPI_FUNCTION_SELECT;
            uint FUNCT_SEL_ADDR = (uint)(test_value1 + test_value2);

            test_value2 = (uint)SPIRegisterMap.SPI_CONTROL;
            uint CONTROL_ADDR = (uint)(test_value1 + test_value2);

            test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_CONTROL;
            uint SHIFT_ADDR = (uint)(test_value1 + test_value2);

            test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_TXD0;
            uint TXD0_ADDR = (uint)(test_value1 + test_value2);

            test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_TXD1;
            uint TXD1_ADDR = (uint)(test_value1 + test_value2);


            test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_RXD0;
            uint RXD0_ADDR = (uint)(test_value1 + test_value2);

            test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_RXD1;
            uint RXD1_ADDR = (uint)(test_value1 + test_value2);

            uint flash_address = Convert.ToUInt32(txtBoxFlashAddress.Text, 16);
            //uint flash_data = Convert.ToUInt32(txtBoxFlashData.Text, 16);

            uint spi_shift_cnt;
            uint spi_rxvld_cnt;
            uint senddata;
            uint recvdata = 0;
            FlashBase fb = new FlashBase(sPortTemp);
            fb.SendRegDataARM(0x1, FUNCT_SEL_ADDR, 0x1, sPortTemp);
            fb.SendEvent += Fb_SendEvent;

            fb.FlashWriteEnable(sPortTemp);
            recvdata = fb.FlashReadStatus(sPortTemp);
            //unprotected
            senddata = (((flash_address & 0xff) << 24) + ((flash_address & 0xff00) << 8) + ((flash_address & 0xff0000) >> 8) + 0x39);
            fb.SendRegDataARM(0x1, TXD0_ADDR, senddata, sPortTemp);
            //SHIFT_CONTROL
            spi_shift_cnt = 32;
            spi_rxvld_cnt = 0;
            senddata = (3 << 16) + (spi_rxvld_cnt << 8) + (spi_shift_cnt << 0);
            fb.SendRegDataARM(0x1, SHIFT_ADDR, senddata, sPortTemp);
            Thread.Sleep(200);

            recvdata = fb.FlashReadStatus(sPortTemp);
            fb.FlashWriteEnable(sPortTemp);
            recvdata = fb.FlashReadStatus(sPortTemp);
            //TXD0
            senddata = (((flash_address & 0xff) << 24) + ((flash_address & 0xff00) << 8) + ((flash_address & 0xff0000) >> 8) + 0x20);
            fb.SendRegDataARM(0x1, TXD0_ADDR, senddata, sPortTemp);
            //SHIFT_CONTROL
            spi_shift_cnt = 32;
            spi_rxvld_cnt = 0;
            senddata = (3 << 16) + (spi_rxvld_cnt << 8) + (spi_shift_cnt << 0);
            fb.SendRegDataARM(0x1, SHIFT_ADDR, senddata, sPortTemp);
            Fb_SendEvent("Flash操作->擦除 执行完成\r\n");
            txtBoxFlashData.Text = string.Empty;
        }

        private void btnReadID_Click(object sender, EventArgs e)
        {
            if (!sPortTemp.IsOpen)
            {
                DevExpress.XtraEditors.XtraMessageBox.Show("串口没有打开");
                return;
            }
            //if (!Regex.Match(txtBoxFlashAddress.Text, @"^[A-Za-z0-9]+$").Success)
            //{
            //    return;
            //}
            ErasePrecent.EditValue = 0;
            Fb_SendEvent("Flash操作->读ReadID 执行开始\r\n");
            long test_value1 = (long)BaseRegisterMap.SPI_BASE_ADDR;

            uint test_value2 = (uint)SPIRegisterMap.SPI_FUNCTION_SELECT;
            uint FUNCT_SEL_ADDR = (uint)(test_value1 + test_value2);

            test_value2 = (uint)SPIRegisterMap.SPI_CONTROL;
            uint CONTROL_ADDR = (uint)(test_value1 + test_value2);

            test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_CONTROL;
            uint SHIFT_ADDR = (uint)(test_value1 + test_value2);

            test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_TXD0;
            uint TXD0_ADDR = (uint)(test_value1 + test_value2);

            test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_TXD1;
            uint TXD1_ADDR = (uint)(test_value1 + test_value2);


            test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_RXD0;
            uint RXD0_ADDR = (uint)(test_value1 + test_value2);

            test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_RXD1;
            uint RXD1_ADDR = (uint)(test_value1 + test_value2);

            uint spi_shift_cnt;
            uint spi_rxvld_cnt;
            uint senddata;
            uint recvdata = 0;
            uint op_code = 0x90;

            FlashBase fb = new FlashBase(sPortTemp);
            fb.SendRegDataARM(0x1, FUNCT_SEL_ADDR, 0x1, sPortTemp);
            fb.SendEvent += Fb_SendEvent;
            //spi cs 片选
            uint spi_cs = 1;
            fb.ReadRegDataARM(0x11, CONTROL_ADDR, ref recvdata, sPortTemp);

            senddata = recvdata & 0xffff3cff;
            senddata = senddata + (spi_cs << 8);
            fb.SendRegDataARM(0x1, CONTROL_ADDR, senddata, sPortTemp);
            //TXD0
            senddata = op_code;
            fb.SendRegDataARM(0x1, TXD0_ADDR, senddata, sPortTemp);
            //SHIFT_CONTROL
            spi_shift_cnt = 64;
            spi_rxvld_cnt = 32;
            senddata = (3 << 16) + (spi_rxvld_cnt << 8) + (spi_shift_cnt << 0);
            fb.SendRegDataARM(0x1, SHIFT_ADDR, senddata, sPortTemp);

            Thread.Sleep(200);
            fb.ReadRegDataARM(0x11, RXD0_ADDR, ref recvdata, sPortTemp);
            this.txtBoxFlashData.Text = Convert.ToString(recvdata, 16).ToUpper();
            Fb_SendEvent("Flash操作->读ReadID 执行结束\r\n");
        }

        private void btnFullChipErase_Click(object sender, EventArgs e)
        {
            if (!sPortTemp.IsOpen)
            {
                DevExpress.XtraEditors.XtraMessageBox.Show("串口没有打开");
                return;
            }
            ErasePrecent.EditValue = 0;
            Fb_SendEvent("Flash操作->整片擦除 执行开始\r\n");
            uint FlashSize = uint.Parse(comboBoxFlashSize.EditValue.ToString());
            uint Flash_Address_Total = FlashSize ;

            long test_value1 = (long)BaseRegisterMap.SPI_BASE_ADDR;

            uint test_value2 = (uint)SPIRegisterMap.SPI_FUNCTION_SELECT;
            uint FUNCT_SEL_ADDR = (uint)(test_value1 + test_value2);

            test_value2 = (uint)SPIRegisterMap.SPI_CONTROL;
            uint CONTROL_ADDR = (uint)(test_value1 + test_value2);

            test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_CONTROL;
            uint SHIFT_ADDR = (uint)(test_value1 + test_value2);

            test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_TXD0;
            uint TXD0_ADDR = (uint)(test_value1 + test_value2);

            test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_TXD1;
            uint TXD1_ADDR = (uint)(test_value1 + test_value2);


            test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_RXD0;
            uint RXD0_ADDR = (uint)(test_value1 + test_value2);

            test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_RXD1;
            uint RXD1_ADDR = (uint)(test_value1 + test_value2);

            uint flash_address = 0;
            //uint flash_data = Convert.ToUInt32(txtBoxFlashData.Text, 16);

            uint spi_shift_cnt;
            uint spi_rxvld_cnt;
            uint senddata;
            uint recvdata = 0;

            FlashBase fb = new FlashBase(sPortTemp);
            fb.SendEvent += Fb_SendEvent;
            while (flash_address < Flash_Address_Total)
            {
                fb.SendRegDataARM(0x1, FUNCT_SEL_ADDR, 0x1, sPortTemp);
                fb.FlashWriteEnable(sPortTemp);
                recvdata = fb.FlashReadStatus(sPortTemp);

                senddata = (((flash_address & 0xff) << 24) + ((flash_address & 0xff00) << 8) + ((flash_address & 0xff0000) >> 8) + 0x39);
                fb.SendRegDataARM(0x1, TXD0_ADDR, senddata, sPortTemp);

                spi_shift_cnt = 32;
                spi_rxvld_cnt = 0;
                senddata = (3 << 16) + (spi_rxvld_cnt << 8) + (spi_shift_cnt << 0);
                fb.SendRegDataARM(0x1, SHIFT_ADDR, senddata, sPortTemp);
                Thread.Sleep(200);

                recvdata = fb.FlashReadStatus(sPortTemp);
                fb.FlashWriteEnable(sPortTemp);
                recvdata = fb.FlashReadStatus(sPortTemp);

                senddata = (((flash_address & 0xff) << 24) + ((flash_address & 0xff00) << 8) + ((flash_address & 0xff0000) >> 8) + 0xD8);  //ERASE 64KB 
                fb.SendRegDataARM(0x1, TXD0_ADDR, senddata, sPortTemp);

                spi_shift_cnt = 32;
                spi_rxvld_cnt = 0;
                senddata = (3 << 16) + (spi_rxvld_cnt << 8) + (spi_shift_cnt << 0);
                fb.SendRegDataARM(0x1, SHIFT_ADDR, senddata, sPortTemp);
                flash_address += 0x10000;
                //需要添加休眠
                Thread.Sleep(1000);
                //进度条显示
                Process_Display(flash_address, Flash_Address_Total);
            }
            Fb_SendEvent("Flash操作->整片擦除 执行成功\r\n");
            DevExpress.XtraEditors.XtraMessageBox.Show("整片擦除完毕！");
        }

        private void btnFlashWrite_File_Click(object sender, EventArgs e)
        {
            ErasePrecent.EditValue = 0;
            if (!sPortTemp.IsOpen)
            {
                DevExpress.XtraEditors.XtraMessageBox.Show("串口没有打开");
                return;
            }
            //int i;
            int sendreturn;
            OpenFileDialog openFileDialog1 = new OpenFileDialog();//将打开的地址给ofd
            openFileDialog1.Filter = "TXT Files(*.txt)|*.txt|All Files(*.*)|*.*";
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    Fb_SendEvent("Flash操作->选取txt文件写入Flash 执行开始\r\n");
                    string txt_str = string.Empty;
                    string[] ss;

                    StreamReader f2 = new StreamReader(openFileDialog1.FileName, System.Text.Encoding.GetEncoding("gb2312"));//gb2312编码，为制定文件名初始化
                    StreamReader f1 = new StreamReader(openFileDialog1.FileName, System.Text.Encoding.GetEncoding("gb2312"));//gb2312编码，为制定文件名初始化

                    long test_value1 = (long)BaseRegisterMap.SPI_BASE_ADDR;

                    uint test_value2 = (uint)SPIRegisterMap.SPI_FUNCTION_SELECT;
                    uint FUNCT_SEL_ADDR = (uint)(test_value1 + test_value2);

                    test_value2 = (uint)SPIRegisterMap.SPI_CONTROL;
                    uint CONTROL_ADDR = (uint)(test_value1 + test_value2);

                    test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_CONTROL;
                    uint SHIFT_ADDR = (uint)(test_value1 + test_value2);

                    test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_TXD0;
                    uint TXD0_ADDR = (uint)(test_value1 + test_value2);

                    test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_TXD1;
                    uint TXD1_ADDR = (uint)(test_value1 + test_value2);


                    test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_RXD0;
                    uint RXD0_ADDR = (uint)(test_value1 + test_value2);

                    test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_RXD1;
                    uint RXD1_ADDR = (uint)(test_value1 + test_value2);

                    test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_TXD2;
                    uint TXD2_ADDR = (uint)(test_value1 + test_value2);

                    test_value2 = (uint)SPIRegisterMap.SPI_INT_STATUS;
                    uint SPI_INT_STATUS_ADDR = (uint)(test_value1 + test_value2);

                    uint spi_shift_cnt;
                    uint spi_rxvld_cnt;
                    uint senddata;
                    uint recvdata = 0;

                    FlashBase fb = new FlashBase(sPortTemp);
                    fb.SendEvent += Fb_SendEvent;
                    fb.SendRegDataARM(0x1, FUNCT_SEL_ADDR, 0x1, sPortTemp);
                    recvdata = fb.FlashReadStatus(sPortTemp);

                    uint flash_address_old = 1;
                    uint flash_address = Convert.ToUInt32(txtBoxBaseFlashAddress.Text, 16);
                    uint Flash_Address_Total = 0;
                    int lines = 0;


                    while (f1.ReadLine() != null)
                    {
                        lines++;
                    }
                    if (lines == 0)
                    {
                        DevExpress.XtraEditors.XtraMessageBox.Show("文件无内容！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }

                    Flash_Address_Total = (uint)lines * 4 + Convert.ToUInt32(txtBoxBaseFlashAddress.Text, 16);

                    ErasePrecent.Properties.Maximum = Convert.ToInt32(Flash_Address_Total);
                    ErasePrecent.Properties.Step = ErasePrecent.Properties.Maximum / 100;
                    while (flash_address < Flash_Address_Total)
                    {
                        Fb_SendEvent(string.Format("txt文件写入Flash 地址:{0} \r\n", flash_address.ToString("X8")));
                        #region while循环代码块
                        if (flash_address + 8 <= Flash_Address_Total)
                        {
                            #region  if 判断逻辑块
                            if ((flash_address & 0xffff0000) != flash_address_old)
                            {
                                flash_address_old = flash_address & 0xff0000;
                                Thread.Sleep(10);
                                fb.FlashWriteEnable(sPortTemp);
                                //unprotected
                                senddata = (((flash_address & 0xff) << 24) + ((flash_address & 0xff00) << 8) + ((flash_address & 0xff0000) >> 8) + 0x39);
                                fb.SendRegDataARM(0x1, TXD0_ADDR, senddata, sPortTemp);
                                //SHIFT_CONTROL
                                spi_shift_cnt = 32;
                                spi_rxvld_cnt = 0;
                                senddata = (3 << 16) + (spi_rxvld_cnt << 8) + (spi_shift_cnt << 0);
                                fb.SendRegDataARM(0x1, SHIFT_ADDR, senddata, sPortTemp);
                                Thread.Sleep(10);
                                fb.FlashWriteEnable(sPortTemp);
                                // erase sector
                                //TXD0
                                senddata = (((flash_address & 0xff) << 24) + ((flash_address & 0xff00) << 8) + ((flash_address & 0xff0000) >> 8) + 0x20);
                                fb.SendRegDataARM(0x1, TXD0_ADDR, senddata, sPortTemp);
                                Thread.Sleep(10);
                                //SHIFT_CONTROL
                                spi_shift_cnt = 32;
                                spi_rxvld_cnt = 0;
                                senddata = (3 << 16) + (spi_rxvld_cnt << 8) + (spi_shift_cnt << 0);
                                fb.SendRegDataARM(0x1, SHIFT_ADDR, senddata, sPortTemp);
                                Thread.Sleep(10);
                            }
                            if ((flash_address & 0xfff) == 0x0)
                            {
                                fb.FlashWriteEnable(sPortTemp);
                                //TXD0
                                senddata = (((flash_address & 0xff) << 24) + ((flash_address & 0xff00) << 8) + ((flash_address & 0xff0000) >> 8) + 0x20);
                                fb.SendRegDataARM(0x1, TXD0_ADDR, senddata, sPortTemp);

                                //SHIFT_CONTROL
                                spi_shift_cnt = 32;
                                spi_rxvld_cnt = 0;
                                senddata = (3 << 16) + (spi_rxvld_cnt << 8) + (spi_shift_cnt << 0);
                                fb.SendRegDataARM(0x1, SHIFT_ADDR, senddata, sPortTemp);
                                Thread.Sleep(10);
                            }

                            recvdata = fb.FlashReadStatus(sPortTemp);
                            while ((recvdata & 0x1) != 0)
                            {
                                Thread.Sleep(1);
                                recvdata = fb.FlashReadStatus(sPortTemp);
                            }
                            fb.FlashWriteEnable(sPortTemp);
                            recvdata = fb.FlashReadStatus(sPortTemp);
                            if ((recvdata & 0x2) == 0)
                            {
                                Fb_SendEvent(string.Format("write enable error \n{0}\n", Convert.ToString(flash_address, 16).ToUpper()));
                            }

                            senddata = (((flash_address & 0xff) << 24) + ((flash_address & 0xff00) << 8) + ((flash_address & 0xff0000) >> 8) + 0x02);
                            sendreturn = fb.SendRegDataARM(0x1, TXD0_ADDR, senddata, sPortTemp);
                            //读TXD0
                            fb.ReadRegDataARM(0x11, TXD0_ADDR, ref recvdata, sPortTemp);
                            if (recvdata != senddata)
                            {
                                Fb_SendEvent(string.Format("write error TXD0:\n{0}\n{1}\n{2}\n", Convert.ToString(sendreturn, 16).ToUpper(), Convert.ToString(senddata, 16).ToUpper(), Convert.ToString(recvdata, 16).ToUpper()));
                            }
                            //TXD1
                            ss = f2.ReadLine().Trim().Split(',');
                            senddata = Convert.ToUInt32(ss[0], 16);
                            fb.SendRegDataARM(0x1, TXD1_ADDR, senddata, sPortTemp);
                            //TXD2
                            ss = f2.ReadLine().Trim().Split(',');
                            senddata = Convert.ToUInt32(ss[0], 16);
                            fb.SendRegDataARM(0x1, TXD2_ADDR, senddata, sPortTemp);
                            //SPI_INT_STATUS清零
                            senddata = 1;
                            fb.SendRegDataARM(0x1, SPI_INT_STATUS_ADDR, senddata, sPortTemp);

                            //SHIFT_CONTROL
                            spi_shift_cnt = 96; // 64;
                            spi_rxvld_cnt = 0;
                            senddata = (3 << 16) + (spi_rxvld_cnt << 8) + (spi_shift_cnt << 0);
                            fb.SendRegDataARM(0x1, SHIFT_ADDR, senddata, sPortTemp);

                            Thread.Sleep(10);

                            if (sendreturn == 0xff)
                            {
                                Fb_SendEvent(string.Format("write error shift_cnt:{0}", Convert.ToString(flash_address, 16).ToUpper()));
                            }
                            for (int j = 0; j < 10; j++)
                            {
                                fb.ReadRegDataARM(0x11, SPI_INT_STATUS_ADDR, ref recvdata, sPortTemp);
                                if (recvdata != 0) break;
                                Thread.Sleep(1);
                            }
                            flash_address = flash_address + 8;
                            #endregion
                        }
                        else
                        {
                            #region else 逻辑块代码
                            uint Byte_Left = Flash_Address_Total - flash_address;//calc left bytes
                            if (Byte_Left == 4)
                            {
                                if ((flash_address & 0xffff0000) != flash_address_old)
                                {
                                    flash_address_old = flash_address & 0xff0000;
                                    Thread.Sleep(2);
                                    fb.FlashWriteEnable(sPortTemp);
                                    senddata = (((flash_address & 0xff) << 24) + ((flash_address & 0xff00) << 8) + ((flash_address & 0xff0000) >> 8) + 0x39);
                                    fb.SendRegDataARM(0x1, TXD0_ADDR, senddata, sPortTemp);
                                    //SHIFT_CONTROL
                                    spi_shift_cnt = 32;
                                    spi_rxvld_cnt = 0;
                                    senddata = (3 << 16) + (spi_rxvld_cnt << 8) + (spi_shift_cnt << 0);
                                    fb.SendRegDataARM(0x1, SHIFT_ADDR, senddata, sPortTemp);
                                    Thread.Sleep(1);
                                    fb.FlashWriteEnable(sPortTemp);
                                    //TXD0
                                    senddata = (((flash_address & 0xff) << 24) + ((flash_address & 0xff00) << 8) + ((flash_address & 0xff0000) >> 8) + 0x20);
                                    fb.SendRegDataARM(0x1, TXD0_ADDR, senddata, sPortTemp);
                                    spi_shift_cnt = 32;
                                    spi_rxvld_cnt = 0;
                                    senddata = (3 << 16) + (spi_rxvld_cnt << 8) + (spi_shift_cnt << 0);
                                    fb.SendRegDataARM(0x1, SHIFT_ADDR, senddata, sPortTemp);
                                    Thread.Sleep(2);
                                }
                                if ((flash_address & 0xfff) == 0x0)
                                {
                                    fb.FlashWriteEnable(sPortTemp);
                                    //TXD0
                                    senddata = (((flash_address & 0xff) << 24) + ((flash_address & 0xff00) << 8) + ((flash_address & 0xff0000) >> 8) + 0x20);
                                    fb.SendRegDataARM(0x1, SHIFT_ADDR, senddata, sPortTemp);
                                    Thread.Sleep(2);
                                    //SHIFT_CONTROL
                                    spi_shift_cnt = 32;
                                    spi_rxvld_cnt = 0;
                                    senddata = (3 << 16) + (spi_rxvld_cnt << 8) + (spi_shift_cnt << 0);
                                    fb.SendRegDataARM(0x1, SHIFT_ADDR, senddata, sPortTemp);
                                    Thread.Sleep(2);
                                }
                                recvdata = fb.FlashReadStatus(sPortTemp);
                                while ((recvdata & 0x1) != 0)
                                {
                                    Thread.Sleep(1);
                                    recvdata = fb.FlashReadStatus(sPortTemp);
                                }
                                fb.FlashWriteEnable(sPortTemp);
                                recvdata = fb.FlashReadStatus(sPortTemp);
                                if ((recvdata & 0x2) == 0)
                                {
                                    Fb_SendEvent(string.Format("write enable error \n{0}\n", Convert.ToString(flash_address, 16).ToUpper()));
                                }
                                senddata = (((flash_address & 0xff) << 24) + ((flash_address & 0xff00) << 8) + ((flash_address & 0xff0000) >> 8) + 0x02);
                                sendreturn = fb.SendRegDataARM(0x1, TXD0_ADDR, senddata, sPortTemp);

                                fb.ReadRegDataARM(0x11, TXD0_ADDR, ref recvdata, sPortTemp);
                                if (recvdata != senddata)
                                {
                                    Fb_SendEvent(string.Format("write error TXD0:\n{0}\n{1}\n{2}\n", Convert.ToString(sendreturn, 16).ToUpper(), Convert.ToString(senddata, 16).ToUpper(), Convert.ToString(recvdata, 16).ToUpper()));
                                }
                                ss = f2.ReadLine().Trim().Split(',');
                                senddata = Convert.ToUInt32(ss[0], 16);
                                fb.SendRegDataARM(0x1, TXD1_ADDR, senddata, sPortTemp);

                                senddata = 1;
                                fb.SendRegDataARM(0x1, SPI_INT_STATUS_ADDR, senddata, sPortTemp);

                                spi_shift_cnt = 64; // 64;
                                spi_rxvld_cnt = 0;
                                senddata = (3 << 16) + (spi_rxvld_cnt << 8) + (spi_shift_cnt << 0);
                                fb.SendRegDataARM(0x1, SHIFT_ADDR, senddata, sPortTemp);
                                Thread.Sleep(2);
                                if (sendreturn == 0xff)
                                {
                                    Fb_SendEvent(string.Format("write error shift_cnt:{0}", Convert.ToString(flash_address, 16).ToUpper()));
                                }
                                for (int j = 0; j < 10; j++)
                                {
                                    fb.ReadRegDataARM(0x11, SPI_INT_STATUS_ADDR, ref recvdata, sPortTemp);
                                    if (recvdata != 0) break;
                                    Thread.Sleep(2);
                                }
                                flash_address = Flash_Address_Total;
                            }
                            #endregion
                        }

                        #endregion

                        //Process_Display(flash_address, Flash_Address_Total);
                        //进度条显示
                        //处理当前消息队列中的所有windows消息
                        //Application.DoEvents();
                        //当前线程挂起指定的时间,这个是为了演示
                        //System.Threading.Thread.Sleep(10);
                        //执行步长
                        //ErasePrecent.PerformStep();
                    }
                    f1.Close();
                    f1.Dispose();
                    f2.Close();
                    f2.Dispose();
                    ErasePrecent.EditValue = ErasePrecent.Properties.Maximum;
                    Fb_SendEvent("Flash操作->选取txt文件写入Flash 执行完毕\r\n");
                    DevExpress.XtraEditors.XtraMessageBox.Show("Flash烧写完毕");
                }
                catch (Exception ex)
                {
                    Fb_SendEvent("Flash操作->选取txt文件写入Flash 错误：" + ex.Message.ToString() + "\r\n");
                    DevExpress.XtraEditors.XtraMessageBox.Show(ex.Message.ToString(), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }


        /// <summary>
        /// 从Flash中导出(txt)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnReadFlashToTxtFile_Click(object sender, EventArgs e)
        {
            Fb_SendEvent("Flash操作->从Flash中导出(txt) 执行开始\r\n");
            ErasePrecent.EditValue = 0;
            if (!sPortTemp.IsOpen)
            {
                DevExpress.XtraEditors.XtraMessageBox.Show("串口没有打开");
                return;
            }
            uint i = 0;
            uint StartAddr = Convert.ToUInt32(txtBoxBaseFlashAddress.Text, 16);
            uint Length = Convert.ToUInt32(textBox_Length.Text, 16);

            ErasePrecent.Properties.Maximum = Convert.ToInt32(textBox_Length.Text, 16);
            ErasePrecent.Properties.Step = 1;
            if (Length == 0)
            {
                DevExpress.XtraEditors.XtraMessageBox.Show("长度不能为0", "错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            //string localFilePath, fileNameExt, newFileName, FilePath; 
            SaveFileDialog sfd = new SaveFileDialog();

            //设置文件类型 
            sfd.Filter = "Flash文件（*.txt）|*.txt";

            //设置默认文件类型显示顺序 
            sfd.FilterIndex = 1;

            //保存对话框是否记忆上次打开的目录 
            sfd.RestoreDirectory = true;

            //设置文件名
            sfd.FileName = string.Format("Flash_Data_StartAddr_0x{0}_Length_0x{1}_{2}", StartAddr.ToString("X8"), Length.ToString("X8"), DateTime.Now.ToString("yyyyMMddHHmm"));

            if (sfd.ShowDialog() == DialogResult.OK)
            {
                string localFilePath = sfd.FileName.ToString(); //获得文件路径 
                StreamWriter sw = File.CreateText(localFilePath);
                FlashBase fb = new FlashBase(sPortTemp);
                fb.SendEvent += Fb_SendEvent;
                StringBuilder sb = new StringBuilder();
                for (i = 0; i < Length; i = i + 4)
                {
                    sb.Append(string.Format("0x{0},\r\n", fb.FastReadFlash((StartAddr + i), sPortTemp).ToString("X8")));
                    Process_Display(i, Length);
                }
                sw.WriteLine(sb.ToString());
                sw.Flush();
                sw.Close();
                Fb_SendEvent("Flash操作->从Flash中导出(txt) 执行完毕\r\n");
                ErasePrecent.EditValue = ErasePrecent.Properties.Maximum;
                DevExpress.XtraEditors.XtraMessageBox.Show(string.Format("导出成功！文件路径：{0}", localFilePath), "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);

            }
        }


        private void Process_Display(uint flash_address, uint Flash_Address_Total)
        {
            this.Invoke((EventHandler)(delegate
            {
                if (flash_address == Flash_Address_Total)
                {
                    ErasePrecent.EditValue = Flash_Address_Total;
                }
                else
                {
                    if (ErasePrecent.Position != Flash_Address_Total)
                    {
                        //处理当前消息队列中的所有windows消息
                        Application.DoEvents();
                        //当前线程挂起指定的时间,这个是为了演示
                        System.Threading.Thread.Sleep(10);
                        //执行步长
                        ErasePrecent.PerformStep();
                    }
                }
            }));


        }

        private void eepromcheck_CheckedChanged(object sender, EventArgs e)
        {
            SetTxRxPath();
        }
        /// <summary>
        /// 设置文件生成
        /// </summary>
        void SetTxRxPath()
        {

            if (!string.IsNullOrEmpty(this.textEdit1.Text))
            {
                //读到长度 生成文件
                var binlength = SYSHelper.BinReader(textEdit1.Text);
                var listbin = SYSHelper.GetUintToList(binlength, 8);
                if (comBoxAgreement.EditValue.ToString() == "0") //表示1kxmodel
                {
                    //更新长度 // 修改成接收
                    SYSHelper.SetRxFlashLength(listbin, ParaList.Rx_flash_1k);
                    SYSHelper.SetRxFlashEeprom(ParaList.Rx_flash_1k, false, eepromcheck.Checked);
                    rxPath = string.Format("{0}\\Lib\\RxFlash1K.txt", Application.StartupPath);
                    if (subsectioncheck.Checked)
                    {
                        SubsetionText1kXmodem();
                        //这里只固定了1kxmodem的方式进行修改  如果是Xmodem模式 这里需要修改
                        ParaList.Rx_flash_1k.ForEach(c =>
                        {
                            if (c.PKey == "0x1329")
                            {
                                c.PValue = "0x06";
                            }
                        });
                    }
                    var tStr = SYSHelper.CreateRxFlash1K();
                   
                    if (File.Exists(rxPath))
                    {
                        File.Delete(rxPath);
                    }
                    //写入文件
                    File.WriteAllText(rxPath, tStr);
                    //增加全局的需要写入功能
                    rxPath = string.Format("{0}\\Lib\\xc151_Bin\\RxFlash1K.txt", Application.StartupPath);
                    File.WriteAllText(rxPath, tStr);
                    //生成写入数据
                    XmodemData.XmodemDataList(textEdit1.Text, true);
                }
                else
                {
                    //表示xmodel //修改成接收
                    SYSHelper.SetRxFlashLength(listbin, ParaList.Rx_flash);
                    SYSHelper.SetRxFlashEeprom(ParaList.Rx_flash, true, eepromcheck.Checked);
                    rxPath = string.Format("{0}\\Lib\\RxFlash.txt", Application.StartupPath);
                    var tStr = SYSHelper.CreateRxFlash();
                    if (File.Exists(rxPath))
                    {
                        File.Delete(rxPath);
                    }
                    //写入文件
                    File.WriteAllText(rxPath, tStr);

                    //生成写入数据
                    XmodemData.XmodemDataList(textEdit1.Text, false);
                }
            }
            if (!string.IsNullOrEmpty(this.textEdit3.Text) && textEdit3.Text != "0000")
            {
                var sysStr = textEdit3.Text.PadLeft(8, '0').ToList();
                List<string> listbin = new List<string>();
                for (int i = 0; i < sysStr.Count;)
                {
                    listbin.Add(string.Format("{0}{1}", sysStr[i], sysStr[i + 1]));
                    i += 2;
                }
                if (comBoxAgreement.EditValue.ToString() == "0") //表示1kxmodel
                {
                    //更新长度 // 修改成接收
                    SYSHelper.SetTxFlashLength(listbin, ParaList.Tx_flash_1k);
                    SYSHelper.SetTxFlashEeprom(ParaList.Tx_flash_1k, false, eepromcheck.Checked);
                    txPath = string.Format("{0}\\Lib\\TxFlash1K.txt", Application.StartupPath);
                    var tStr = SYSHelper.CreateTxFlash1K();
                    if (File.Exists(txPath))
                    {
                        File.Delete(txPath);
                    }
                    //写入文件
                    File.WriteAllText(txPath, tStr);
                    //增加全局的需要写入功能
                    txPath = string.Format("{0}\\Lib\\xc151_Bin\\TxFlash1K.txt", Application.StartupPath);
                    File.WriteAllText(txPath, tStr);
                }
                else
                {
                    //表示xmodel //修改成接收
                    SYSHelper.SetTxFlashLength(listbin, ParaList.Tx_flash);
                    SYSHelper.SetTxFlashEeprom(ParaList.Tx_flash, true, eepromcheck.Checked);
                    txPath = string.Format("{0}\\Lib\\TxFlash.txt", Application.StartupPath);
                    var tStr = SYSHelper.CreateTxFlash();
                    if (File.Exists(txPath))
                    {
                        File.Delete(txPath);
                    }
                    //写入文件
                    File.WriteAllText(txPath, tStr);

                }
            }
        }

        private void simpleButton2_Click(object sender, EventArgs e)
        {
            comBoxPorts.Properties.ValueMember = "ValueMember";
            comBoxPorts.Properties.DisplayMember = "DisplayMember";
            comBoxPorts.Properties.DataSource = XModem.library.Port.GetPorts();
            comBoxPorts.ItemIndex = 0;
        }

        private void comBoxBaudRate_Leave(object sender, EventArgs e)
        {
            var ds = comBoxBaudRate.Properties.DataSource as List<TreeListValue>;
            if (ds.Where(c => c.DisplayMember == comBoxBaudRate.Text).Count() == 0)
            {
                ds.Add(new TreeListValue() { DisplayMember = comBoxBaudRate.Text, ValueMember = comBoxBaudRate.Text });
            }
        }
        #region 写保护相关方法
        private byte ReadStatusFlash()
        {
            long test_value1 = (long)BaseRegisterMap.SPI_BASE_ADDR;
            uint test_value2 = (uint)SPIRegisterMap.SPI_FUNCTION_SELECT;
            uint FUNCT_SEL_ADDR = (uint)(test_value1 + test_value2);

            test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_TXD0;
            uint TXD0_ADDR = (uint)(test_value1 + test_value2);
            test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_CONTROL;
            uint SHIFT_ADDR = (uint)(test_value1 + test_value2);

            uint RXD0_ADDR = (uint)BaseRegisterMap.SPI_BASE_ADDR + (uint)SPIRegisterMap.SPI_SHIFT_RXD0;
            fb.SendRegDataARM(0x1, FUNCT_SEL_ADDR, 1, sPortTemp);

            uint spi_shift_cnt;
            uint spi_rxvld_cnt;
            uint status = 0;
            uint op_code = 0x05;
            uint senddata = op_code;

            SPI_Status_Clear();
            fb.SendRegDataARM(0x1, TXD0_ADDR, senddata,sPortTemp);
            spi_shift_cnt = 16;
            spi_rxvld_cnt = 8;
            senddata = (3 << 16) + (spi_rxvld_cnt << 8) + (spi_shift_cnt);
            fb.SendRegDataARM(0x1, SHIFT_ADDR, senddata,sPortTemp);
            SPI_WaitReady();
            SPI_Status_Clear();
            fb.ReadRegDataARM(0x11, RXD0_ADDR, ref status, sPortTemp);
            return (byte)(status & 0xff);
        }

        private void SPI_Status_Clear()
        {
            uint BUSY_FM_ADDR;
            uint SPI_BUSY_FM = 0x40;
            BUSY_FM_ADDR = (uint)BaseRegisterMap.SPI_BASE_ADDR + SPI_BUSY_FM;

            #region BUSY_FM_ADDR写1 
            // /*  小端
            uint reg_address = BUSY_FM_ADDR;
            int byte_sel = (int)(reg_address) & 0x3;
            byte_sel = byte_sel * 8;
            uint reg_data = 1;
            reg_data = reg_data & 0xff;
            reg_data = reg_data << byte_sel;

            fb.SendRegDataARM(0x21, reg_address, reg_data, sPortTemp);
            #endregion

        }
        private void SPI_WaitReady()
        {
            uint time_out = 3;
            uint BUSY_ADDR;
            uint BUSY_FM_ADDR;
            uint test_value1 = (uint)BaseRegisterMap.SPI_BASE_ADDR;
            uint test_value2 = (uint)SPIRegisterMap.SPI_BUSY;
            BUSY_ADDR = test_value1 + test_value2;
            BUSY_FM_ADDR = test_value1 + (uint)SPIRegisterMap.SPI_BUSY_FM;

            uint data = 0;
            do
            {
                Thread.Sleep(10);
                fb.ReadRegDataARM(0x31, BUSY_FM_ADDR, ref data, sPortTemp);
            }
            while ((data != 2) && (time_out-- > 0));
            if (time_out <= 0)
            {
                MessageBox.Show("spi wait busy_status time out");
            }
        }

        void DisableWriteProtect()
        {
            //WriteStatusRegister((byte)(ReadStatusFlash() & 0x7f));//srp0写0
            WriteStatusRegister((byte)(ReadStatusFlash() & 0xe3));
        }
        void EnableWriteProtect()
        {
            //WriteStatusRegister((byte)(ReadStatusFlash() & 0x7f));//srp0写0
            WriteStatusRegister((byte)(ReadStatusFlash() | 0x1c));
        }
        void WriteStatusRegister(byte nStatus)
        {
            uint spi_base_addr = (uint)BaseRegisterMap.SPI_BASE_ADDR;
            uint FUNCT_SEL_ADDR = spi_base_addr + (uint)SPIRegisterMap.SPI_FUNCTION_SELECT;
            uint CONTROL_ADDR = spi_base_addr + (uint)SPIRegisterMap.SPI_CONTROL;
            uint RESERVED_ADDR = spi_base_addr + (uint)SPIRegisterMap.SPI_RESERVED;
            uint SHIFT_ADDR = spi_base_addr + (uint)SPIRegisterMap.SPI_SHIFT_CONTROL;
            uint TXD0_ADDR = spi_base_addr + (uint)SPIRegisterMap.SPI_SHIFT_TXD0;
            uint spi_shift_cnt;
            uint spi_rxvld_cnt;
            uint senddata;

            //spi_enable
            simpleButton11_Click(null, null);
            SPI_Status_Clear();
            fb.SendRegDataARM(0x1, FUNCT_SEL_ADDR, 0x01, sPortTemp);
            while ((ReadStatusFlash() & 0x01) == 0x01) ;
            fb.SendRegDataARM(0x1, TXD0_ADDR, 0x06, sPortTemp);
            spi_shift_cnt = 8;
            spi_rxvld_cnt = 0;
            senddata = (3 << 16) + (spi_rxvld_cnt << 8) + (spi_shift_cnt);
            fb.SendRegDataARM(0x1, SHIFT_ADDR, senddata, sPortTemp);
            SPI_WaitReady();
            while ((ReadStatusFlash() & 0x01) == 0x01) ;
            senddata = (uint)((nStatus << 8) + 0x01);
            SPI_Status_Clear();
            fb.SendRegDataARM(0x1, TXD0_ADDR, senddata, sPortTemp);
            spi_shift_cnt = 16;
            spi_rxvld_cnt = 0;
            senddata = (3 << 16) + (spi_rxvld_cnt << 8) + (spi_shift_cnt);
            fb.SendRegDataARM(0x1, SHIFT_ADDR, senddata, sPortTemp);
            SPI_WaitReady();
            while ((ReadStatusFlash() & 0x01) == 0x01) ;
        }
        #endregion
        private void simpleButton1_Click(object sender, EventArgs e)
        {
            if ((ReadStatusFlash() & 0x1c) == 0x1c)//是否处于写保护状态
            {//是
                DisableWriteProtect();
                byte status = ReadStatusFlash();
                if ((status & 0x1c) == 0x1c)//是否成功解除
                {
                    Fb_SendEvent("解除写保护失败");
                    simpleButton1.Text = "解除写保护";
                }
                else if ((status & 0x1c) == 0x00)
                {
                    Fb_SendEvent("解除写保护成功");
                    simpleButton1.Text = "开启写保护";
                }
            }
            else
            {//否
                EnableWriteProtect();
                byte status = ReadStatusFlash();
                if ((status & 0x1c) == 0x1c)//是否成功
                {
                    Fb_SendEvent("开启写保护成功");
                    simpleButton1.Text = "解除写保护";
                }
                else if ((status & 0x1c) == 0x00)
                {
                    Fb_SendEvent("开启写保护成功失败");
                    simpleButton1.Text = "开启写保护";
                }
            }
        }
        /// <summary>
        /// get系统频率
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void simpleButton8_Click(object sender, EventArgs e)
        {
            if (sPortTemp.IsOpen)
            {
                CalculationCrystalOscillator();
            }
        }

        private void rx_txt_EditValueChanging(object sender, DevExpress.XtraEditors.Controls.ChangingEventArgs e)
        {

            if (string.IsNullOrEmpty(rx_txt.Text) || string.IsNullOrEmpty(tx_txt.Text) || iscomBox)
            {
                return;
            } 
            if (comBoxAgreement.EditValue.ToString() == "0") //表示1kxmodel
            {
                //tx_txt.Text = ParaList.Tx_flash_1k.First(c => c.PKey == "0x07ad").PValue.Replace("0x", "");
                //rx_txt.Text = ParaList.Rx_flash_1k.First(c => c.PKey == "0x07af").PValue.Replace("0x", "");
                ParaList.Rx_flash_1k.ForEach(c =>
                {
                    if (c.PKey == "0x1340")
                    {
                        c.PValue = $"0x{e.NewValue.ToString()}";
                    }
                });
            }
            else
            {
                ParaList.Rx_flash.ForEach(c =>
                {
                    if (c.PKey == "0x1340")
                    {
                        c.PValue = $"0x{e.NewValue.ToString()}";
                    }
                });

            }
            SetTxRxPath();
        }

        private void tx_txt_EditValueChanging(object sender, DevExpress.XtraEditors.Controls.ChangingEventArgs e)
        {
            if (string.IsNullOrEmpty(rx_txt.Text) || string.IsNullOrEmpty(tx_txt.Text) || iscomBox)
            {
                return;
            }
            if (comBoxAgreement.EditValue.ToString() == "0") //表示1kxmodel
            {

                ParaList.Tx_flash_1k.ForEach(c =>
                {
                    if (c.PKey == "0x133e")
                    {
                        c.PValue = $"0x{e.NewValue.ToString()}";
                    }
                });
            }
            else
            {

                ParaList.Tx_flash.ForEach(c =>
                {
                    if (c.PKey == "0x133e")
                    {
                        c.PValue = $"0x{e.NewValue.ToString()}";
                    }
                });

            }
            SetTxRxPath();
        }

        private void isprintcheck_CheckedChanged(object sender, EventArgs e)
        {
            isPrintShow = !isprintcheck.Checked;
        }
        
        private void btnFlashWriteFile_Click(object sender, EventArgs e)
        {
            if (IsUsbOpen)
            {
                if (!IsUsbOpen)
                {
                    DevExpress.XtraEditors.XtraMessageBox.Show("USB未打开");
                    return;
                }
                OpenFileDialog openFileDialog1 = new OpenFileDialog();
                openFileDialog1.Filter = "|*.*";
                if (openFileDialog1.ShowDialog() == DialogResult.OK)
                {
                    bool isbool;
                    binPBC.Visible = true;
                    binPBC.Properties.Minimum = 0;
                    binPBC.Properties.Maximum = 100;
                    binPBC.Properties.Step = 1;
                    binPBC.Position = 0;
                    binPBC.Properties.ShowTitle = true;
                    binPBC.Properties.PercentView = true;
                    if (IntPtr.Size == 8)
                    {
                        //isbool = XChipUSB.UsbFlashWriteFile64(openFileDialog1.FileName,0x0);
                        
                        this.Invoke(new Action(() =>
                        {
                            //while (isbool)
                            //{
                            
                            //    XChipUSB.CallBackInfo info = XChipUSB.GetProgressInfo64();
                            //    binPBC.Position = info.progress;
                            //    if (info.progress == 100 && info.result >= 0)
                            //    {
                            //        //读写完成跳出
                            //        MessageBox.Show("完成");
                            //        break;
                            //    }
                            //    else if (info.progress == 50 && info.result >= 0)
                            //    {
                            //        MessageBox.Show("进度已经达50");
                            //    }
                            //    else if (info.result < 0)
                            //    {
                            //        //读写异常跳出
                            //        MessageBox.Show("异常跳出");
                            //        break;
                            //    }
                           
                            //}
                        }));
                    }
                    else
                    {
                        //isbool = XChipUSB.UsbFlashWriteFile86(openFileDialog1.FileName, 0x0);
                        //this.Invoke(new Action(() =>
                        //{
                        //    while (isbool)
                        //    {

                        //        XChipUSB.CallBackInfo info = XChipUSB.GetProgressInfo86();
                        //        binPBC.Position = info.progress;
                        //        if (info.progress == 100 && info.result >= 0)
                        //        {
                        //            //读写完成跳出
                        //            MessageBox.Show("完成");
                        //            break;
                        //        }
                        //        else if (info.progress == 50 && info.result >= 0)
                        //        {
                        //            MessageBox.Show("进度已经达50");
                        //        }
                        //        else if (info.result < 0)
                        //        {
                        //            //读写异常跳出
                        //            MessageBox.Show("异常跳出");
                        //            break;
                        //        }

                        //    }
                        //}));
                    }

                }
               
                
            }
        }
        /// <summary>
        /// flash存储大小校验
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void simpleButton7_Click(object sender, EventArgs e)
        {
            WaitBefore.Start("请耐心等待...", "正在努力加载中");
            try
            {
                if (!sPortTemp.IsOpen)
                {
                    DevExpress.XtraEditors.XtraMessageBox.Show("串口没有打开");
                    return;
                }
                //if (!Regex.Match(txtBoxFlashAddress.Text, @"^[A-Za-z0-9]+$").Success)
                //{
                //    return;
                //}
                ErasePrecent.EditValue = 0;
                Fb_SendEvent("Flash操作->读ReadID 执行开始\r\n");
                long test_value1 = (long)BaseRegisterMap.SPI_BASE_ADDR;

                uint test_value2 = (uint)SPIRegisterMap.SPI_FUNCTION_SELECT;
                uint FUNCT_SEL_ADDR = (uint)(test_value1 + test_value2);

                test_value2 = (uint)SPIRegisterMap.SPI_CONTROL;
                uint CONTROL_ADDR = (uint)(test_value1 + test_value2);

                test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_CONTROL;
                uint SHIFT_ADDR = (uint)(test_value1 + test_value2);

                test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_TXD0;
                uint TXD0_ADDR = (uint)(test_value1 + test_value2);

                test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_TXD1;
                uint TXD1_ADDR = (uint)(test_value1 + test_value2);


                test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_RXD0;
                uint RXD0_ADDR = (uint)(test_value1 + test_value2);

                test_value2 = (uint)SPIRegisterMap.SPI_SHIFT_RXD1;
                uint RXD1_ADDR = (uint)(test_value1 + test_value2);

                uint spi_shift_cnt;
                uint spi_rxvld_cnt;
                uint senddata;
                uint recvdata = 0;
                uint op_code = 0x9f;

                FlashBase fb = new FlashBase(sPortTemp);
                fb.SendRegDataARM(0x1, FUNCT_SEL_ADDR, 0x1, sPortTemp);
                fb.SendEvent += Fb_SendEvent;
                //spi cs 片选
                uint spi_cs = 1;
                fb.ReadRegDataARM(0x11, CONTROL_ADDR, ref recvdata, sPortTemp);

                senddata = recvdata & 0xffff3cff;
                senddata = senddata + (spi_cs << 8);
                fb.SendRegDataARM(0x1, CONTROL_ADDR, senddata, sPortTemp);
                //TXD0
                senddata = op_code;
                fb.SendRegDataARM(0x1, TXD0_ADDR, senddata, sPortTemp);
                //SHIFT_CONTROL
                spi_shift_cnt = 64;
                spi_rxvld_cnt = 32;
                senddata = (3 << 16) + (spi_rxvld_cnt << 8) + (spi_shift_cnt << 0);
                fb.SendRegDataARM(0x1, SHIFT_ADDR, senddata, sPortTemp);

                Thread.Sleep(200);
                fb.ReadRegDataARM(0x11, RXD0_ADDR, ref recvdata, sPortTemp);
                var kbytestr = (Math.Pow(2, (recvdata >> 16 & 0xff))/1024);
                FlashSize = (int)kbytestr;
                if (kbytestr!=0xff && kbytestr != 0 && kbytestr % 1 == 0)
                {
                    List<TreeListValue> list = new List<TreeListValue>();
                    list.Add(new TreeListValue() { DisplayMember = $"{kbytestr}k", ValueMember = $"{kbytestr * 1024}" });
                    list.Add(new TreeListValue() { DisplayMember = "4M", ValueMember = $"{4 * 1024 * 1024}" });
                    list.Add(new TreeListValue() { DisplayMember = "8M", ValueMember = $"{8 * 1024 * 1024}" });
                    comboBoxFlashSize.Properties.DataSource = list;
                    comboBoxFlashSize.Properties.ValueMember = "ValueMember";
                    comboBoxFlashSize.Properties.DisplayMember = "DisplayMember";

                    comboBoxFlashSize.ItemIndex = 0;
                    WaitBefore.Close();
                    return;
                }
            }
            catch (Exception)
            {
                throw;
            }


            try
            {
                uint startone = 0x0;
                uint starttwo = 0x4;
                uint startthree = 0x8;
                uint startfour = 0xc;
                var one = FlashRead(startone);
                var two = FlashRead(starttwo);
                var three = FlashRead(startthree);
                var four = FlashRead(startfour);

                if (one == "FFFFFFFF"
                    && two == "FFFFFFFF"
                    && three == "FFFFFFFF"
                    && four == "FFFFFFFF")
                {
                    FlashWrite(startone, 0x00010203);
                    FlashWrite(starttwo, 0x04050607);
                    FlashWrite(startthree, 0x08090a0b);
                    FlashWrite(startfour, 0x0c0d0e0f);
                    one = "00010203";
                    two = "04050607";
                    three = "08090a0b";
                    four = "0c0d0e0f";
                }
                int kbyte = 64;
                one = FlashRead(startone);
                two = FlashRead(starttwo);
                three = FlashRead(startthree);
                four = FlashRead(startfour);
                if (one == "FFFFFFFF"
                     && two == "FFFFFFFF"
                     && three == "FFFFFFFF"
                     && four == "FFFFFFFF")
                {
                    Fb_SendEvent("Flash操作->容量检测失败 请先SPI使能\r\n");
                    return;
                }
                for (uint i = 0x10000; i < 0x400000; i *= 2)
                {
                    if (FlashRead(i) == one
                        && FlashRead(i + 0x4) == two
                        && FlashRead(i + 0x8) == three
                        && FlashRead(i + 0xc) == four)
                    {
                        break;
                    }
                    kbyte *= 2;
                }
                FlashSize = kbyte;
                List<TreeListValue> list = new List<TreeListValue>();
                list.Add(new TreeListValue() { DisplayMember = $"{kbyte}k", ValueMember = $"{kbyte * 1024}" });
                list.Add(new TreeListValue() { DisplayMember = "4M", ValueMember = $"{4 * 1024 * 1024}" });
                list.Add(new TreeListValue() { DisplayMember = "8M", ValueMember = $"{8 * 1024 * 1024}" });
                comboBoxFlashSize.Properties.DataSource = list;
                comboBoxFlashSize.Properties.ValueMember = "ValueMember";
                comboBoxFlashSize.Properties.DisplayMember = "DisplayMember";

                comboBoxFlashSize.ItemIndex = 0;


            }
            catch (Exception)
            {

            }
            finally
            {
                WaitBefore.Close();
            }

        }

        private void simpleButton10_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            openFileDialog1.Filter = "TXT Files(*.xfw)|*.xfw|All Files(*.*)|*.*";
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                UnZipFile(openFileDialog1.FileName);
                string[] binFiles = Directory.GetFiles($"{Application.StartupPath}\\Lib\\XChip_Zip", "*.bin", SearchOption.AllDirectories);
                if (binFiles.Count() <= 0)
                {
                    Close_Process_ByAll();
                    WaitBefore.Close();
                    return;
                }
                textEdit5.Text = openFileDialog1.FileName;
                string firstMatch = binFiles.FirstOrDefault(s => s.Contains("Patch_Bin"));
                openFileDialog1.FileName = firstMatch;
                //转换过后的TXTpatch文件
                PathFile = patch_Copy_Files_For_Header_Patch_Tool(openFileDialog1.FileName, true, "", true, false, 4);
                
            }
        }
        string PathFile ="";
        public string UnZipFile(string TargetFile)
        {
            string fileDir = $"{Application.StartupPath}\\Lib\\XChip_Zip";
            //string[] filePaths = Directory.GetFiles(fileDir);

            //// 遍历所有文件并删除它们  
            //foreach (string filePath in filePaths)
            //{
            //    File.Delete(filePath);
            //}
            try
            {
                RemoveReadOnlyAttributes(fileDir);
                Directory.Delete(fileDir, true);
                Directory.CreateDirectory(fileDir);
            }
            catch (Exception ex)
            {
                return ex.Message;
                throw;
            }

            // 目标文件路径（包括新扩展名）  
            string destinationFilePath = Path.Combine(fileDir, "XChip.zip");
            // 复制文件到目标文件夹  
            File.Copy(TargetFile, destinationFilePath, true); // 第三个参数表示覆盖已存在的文件  

            TargetFile = fileDir + "\\XChip.zip";
            string rootFile = "";
            try
            {
                if (!Directory.Exists(fileDir))
                {
                    Directory.CreateDirectory(fileDir);
                }
                //读取压缩文件（zip文件），准备解压缩
                ZipInputStream inputstream = new ZipInputStream(File.OpenRead(TargetFile.Trim()));
                ZipEntry entry;
                string path = fileDir;
                //解压出来的文件保存路径
                string rootDir = "";
                //根目录下的第一个子文件夹的名称
                while ((entry = inputstream.GetNextEntry()) != null)
                {
                    rootDir = Path.GetDirectoryName(entry.Name);
                    //得到根目录下的第一级子文件夹的名称
                    if (rootDir.IndexOf("\\") >= 0)
                    {
                        rootDir = rootDir.Substring(0, rootDir.IndexOf("\\") + 1);
                    }
                    string dir = Path.GetDirectoryName(entry.Name);
                    //得到根目录下的第一级子文件夹下的子文件夹名称
                    string fileName = Path.GetFileName(entry.Name);
                    //根目录下的文件名称
                    if (dir != "")
                    {
                        //创建根目录下的子文件夹，不限制级别
                        if (!Directory.Exists(fileDir + "\\" + dir))
                        {
                            path = fileDir + "\\" + dir;
                            //在指定的路径创建文件夹
                            Directory.CreateDirectory(path);
                        }
                    }
                    else if (dir == "" && fileName != "")
                    {
                        //根目录下的文件
                        path = fileDir;
                        rootFile = fileName;
                    }
                    else if (dir != "" && fileName != "")
                    {
                        //根目录下的第一级子文件夹下的文件
                        if (dir.IndexOf("\\") > 0)
                        {
                            //指定文件保存路径
                            path = fileDir + "\\" + dir;
                        }
                    }
                    if (dir == rootDir)
                    {
                        //判断是不是需要保存在根目录下的文件
                        path = fileDir + "\\" + rootDir;
                    }

                    //以下为解压zip文件的基本步骤
                    //基本思路：遍历压缩文件里的所有文件，创建一个相同的文件
                    if (fileName != String.Empty)
                    {
                        FileStream fs = File.Create(path + "\\" + fileName);
                        int size = 2048;
                        byte[] data = new byte[2048];
                        while (true)
                        {
                            size = inputstream.Read(data, 0, data.Length);
                            if (size > 0)
                            {
                                fs.Write(data, 0, size);
                            }
                            else
                            {
                                break;
                            }
                        }
                        fs.Close();
                    }
                }
                inputstream.Close();
                return rootFile;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
        //用于取消指定路径下所有文件和子文件夹的只读属性  
        public static void RemoveReadOnlyAttributes(string path)
        {
            try
            {
                // 确认路径存在  
                if (Directory.Exists(path))
                {
                    // 获取目录下的所有文件和子目录  
                    string[] files = Directory.GetFiles(path);
                    string[] subDirectories = Directory.GetDirectories(path);

                    // 遍历所有文件并取消只读属性  
                    foreach (var file in files)
                    {
                        FileInfo fileInfo = new FileInfo(file);
                        if (fileInfo.IsReadOnly)
                        {
                            fileInfo.IsReadOnly = false; // 取消只读属性  
                        }
                    }

                    // 遍历所有子目录并递归取消只读属性  
                    foreach (var subDirectory in subDirectories)
                    {
                        DirectoryInfo directoryInfo = new DirectoryInfo(subDirectory);
                        if (directoryInfo.Attributes.HasFlag(FileAttributes.ReadOnly))
                        {
                            directoryInfo.Attributes &= ~FileAttributes.ReadOnly; // 取消只读属性  
                        }
                        // 递归取消子目录中所有文件和文件夹的只读属性  
                        RemoveReadOnlyAttributes(subDirectory); // 递归调用方法处理子目录中的文件和文件夹  
                    }
                }
                else if (File.Exists(path)) // 如果传入的是文件路径，则直接处理文件  
                {
                    FileInfo fileInfo = new FileInfo(path);
                    if (fileInfo.IsReadOnly)
                    {
                        fileInfo.IsReadOnly = false; // 取消只读属性  
                    }
                }
                else
                {
                    Console.WriteLine("指定的路径不存在。");
                }
            }
            catch (Exception ex)
            {
                // 输出遇到的错误信息  
                Console.WriteLine("发生错误: " + ex.Message);
            }
        }

        public void Close_Process_ByAll()
        {
            Process[] myprocess = Process.GetProcesses();
            foreach (Process p in myprocess)
            {
                //此处需要手动添加app.config 文件下名称
                if (
                   p.ProcessName.Contains(ConfigurationManager.AppSettings["xc151_setting"])
                    || p.ProcessName.Contains(ConfigurationManager.AppSettings["xc151_header"])
                    || p.ProcessName.Contains("cmd")
                    || p.ProcessName.Contains("conhost")
                    || p.ProcessName.Contains("Windows Command Processor"))
                {
                    //p.CloseMainWindow();
                    p.Close();
                    // p.Kill();
                }
            }
        }

        public string patch_Copy_Files_For_Header_Patch_Tool(string Inputfilepath, bool Isflash, string eepromaddr, bool isSetting, bool isHead, int bin_Id)
        {
            string strFileName = System.IO.Path.GetFileName(Inputfilepath); //获取文件名
            strFileName = strFileName.Replace("bin", "txt");
            string strNewSavePath = Application.StartupPath + "\\Lib\\xc151_header\\Flash_" + strFileName;
            //strNewSavePath = "C:\\vsProject\\XChip_Bin&Setting_151\\XChipTool_460\\bin\\Debug\\Lib\\Flash_Code_XC151_patch.txt";
            string bin_str = "";
            string bin_mid = "";
            string header_str = "";
            byte[] binchar = new byte[] { };
            //byte[] binchar1 = new byte[] { };
            int file_len;
            FileStream fileStream = new FileStream(Inputfilepath, FileMode.Open);
            //读二进制文件类
            BinaryReader br = new BinaryReader(fileStream, Encoding.UTF8);
            //获取bin文件长度
            file_len = (int)fileStream.Length;
            //得到所有字节
            binchar = br.ReadBytes(file_len);
            int ii = 0;
            int iheader = 0;
            ////清空之前存储的patch头;
            //if (patchheader.Count !=0)
            //{
            //    patchheader.Clear();
            //} 
            foreach (byte j in binchar)
            {
                if (iheader < 16)//将patch头16字节剔除出来并保存至list容器中；
                {
                    header_str = j.ToString("X2");
                    if (bin_Id == 4)
                    {
                        if (patchheader.Count == 16)
                        {
                            patchheader.Clear();
                        }
                        patchheader.Add(header_str);
                    }
                    

                    iheader++;
                }
                else
                {
                    ////如果选择小端否则大端;
                    //if (litterbigstr.Checked)//大端
                    //{
                    if (ii < 4)//每四个组成一个中间字符串；
                    {
                        if (ii == 3)
                        {
                            bin_str += "0x" + j.ToString("X2") + "," + "\r\n";
                            ii = 0;
                        }
                        else
                        {

                            bin_str += j.ToString("X2");
                            ii++;
                        }
                    }
                }
            }

            //添加crc校验;
            byte[] newArray = new byte[binchar.Length - 16];
            Array.Copy(binchar, 16, newArray, 0, newArray.Length);
            UInt16 crc_check = Setting2FlashE2prom.XchipCrcCheck16(0xFFFF, newArray);
            uint crc_Reg = (uint)((0xfffc << 16) + crc_check);
            string crc_str = crc_Reg.ToString("X8");
            string crc_str1 = SetLitter(crc_str);
            bin_str += "0x" + crc_str1 + "," + "\r\n";
            //关闭 BinaryReader 对象和基础流
            br.Close();
            System.IO.File.WriteAllText(strNewSavePath, bin_str);
            //也可以指定编码方式
            //System.IO.File.WriteAllText(strNewSavePath, bin_str, Encoding.UTF8);

            //patch长度多了四个字节，因为在中间文件尾部加了四个字节得校验;
            if (bin_Id == 4)
            {
                string lenth = FilePathLengthComplement8(strNewSavePath);
                int a = Convert.ToInt32(lenth, 16);
                int inew = a - 4;
                lenth = inew.ToString("X8");
                patchheader[0] = lenth.Substring(0, 2);
                patchheader[1] = lenth.Substring(2, 2);
                patchheader[2] = lenth.Substring(4, 2);
                patchheader[3] = lenth.Substring(6);
            }


            return strNewSavePath;
        }
        public static string SetLitter(string strold)
        {
            string str1 = strold.Substring(0, 2);
            string str2 = strold.Substring(2, 2);
            string str3 = strold.Substring(4, 2);
            string str4 = strold.Substring(6);
            strold = str4 + str3 + str2 + str1;
            return strold;
        }
        public string FilePathLengthComplement8(string mpath)
        {
            int tempLength = File.ReadAllLines(mpath).Length;
            var tempCount = Convert.ToUInt32((tempLength * 4).ToString("x4"), 16);
            return tempCount.ToString("X8");
        }
        public string FilePathLengthComplement(string mpath)
        {
            int tempLength = File.ReadAllLines(mpath).Length;
            var tempCount = Convert.ToUInt32((tempLength * 4).ToString("x4"), 16);
            return tempCount.ToString("X4");
        }
        //头文件校验crc
        public string Copy_Files_For_Header_Patch_Tool(string Inputfilepath, bool Isflash, string eepromaddr, bool isSetting, bool isHead)
        {
            string strFileName = System.IO.Path.GetFileName(Inputfilepath); //获取文件名
            string strNewSavePath = Application.StartupPath + "\\Lib\\xc151_setting\\Flash_" + strFileName;
            if (isHead)
            {
                Setting2FlashE2prom.FlashHeader2Flash(Inputfilepath, strNewSavePath);
            }
            else
            {
                Setting2FlashE2prom.FlashSetting2Flash(Inputfilepath, strNewSavePath, 1, 0, 0);
            }

            return strNewSavePath;
        }

        private void subsectioncheck_CheckedChanged(object sender, EventArgs e)
        {
            if (subsectioncheck.Checked)
            {
                if (!sPortTemp.IsOpen)
                {
                    DevExpress.XtraEditors.XtraMessageBox.Show("可用端口未打开!");
                    return;
                }
                //勾选起始地址后需要读取0x2000026a~0x2000026b的值，如果是0xabcd就让用户填写烧录地址，然后进行自定义烧录操作。
                var nhdr_l = SerialSend.ReadRegister(0x2000026a, sPortTemp);
                var nhdr_h = SerialSend.ReadRegister(0x2000026b, sPortTemp);
                if (nhdr_l == 0x0 || nhdr_h == 0x0)
                {
                    subsectioncheck.Checked = false;
                    DevExpress.XtraEditors.XtraMessageBox.Show("模组Patch未支持自定义起始地址烧录功能!");
                    return;
                }
                subsectiontext.Enabled = true;
            }
            else
            {
                subsectiontext.Text = string.Empty;
                subsectiontext.Enabled = false;
            }


        }

        uint FlashIdx = 0x2000026c;
        /// <summary>
        /// 需要修改发送文件  否则分段烧写无法成功
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void subsectiontext_EditValueChanged(object sender, EventArgs e)
        {
            SubsetionText1kXmodem();

        }

        private void SubsetionText1kXmodem()
        {
            if (string.IsNullOrEmpty(subsectiontext.Text))
            {
                DevExpress.XtraEditors.XtraMessageBox.Show("分段烧写起始地址不能为空！");
                return;
            }
            //这里只固定了1kxmodem的方式进行修改  如果是Xmodem模式 这里需要修改
            var t1 = Convert.ToUInt32(subsectiontext.Text,16) & 0xff;
            var t2 = Convert.ToUInt32(subsectiontext.Text, 16) >> 8 & 0xff;
            var t3 = Convert.ToUInt32(subsectiontext.Text, 16) >> 16 & 0xff;
            var t4 = Convert.ToUInt32(subsectiontext.Text, 16) >> 24 & 0xff;


            SerialSend.WriteRegister(FlashIdx, t1, sPortTemp);
            SerialSend.WriteRegister(FlashIdx + 1, t2, sPortTemp);
            SerialSend.WriteRegister(FlashIdx + 2, t3, sPortTemp);
            SerialSend.WriteRegister(FlashIdx + 3, t4, sPortTemp);

            var index = ParaList.Rx_flash_1k.FindIndex(c => c.PKey == "0xfffd" && c.PValue == "0x80");
            if (ParaList.Rx_flash_1k.Exists(c => c.PKey == $"0x{FlashIdx.ToString("X4").Replace("2000", "")}"))
            {
                ParaList.Rx_flash_1k.Remove(ParaList.Rx_flash_1k.Find(c => c.PKey == $"0x{FlashIdx.ToString("X4").Replace("2000", "")}"));
                ParaList.Rx_flash_1k.Remove(ParaList.Rx_flash_1k.Find(c => c.PKey == $"0x{(FlashIdx + 1).ToString("X4").Replace("2000", "")}"));
                ParaList.Rx_flash_1k.Remove(ParaList.Rx_flash_1k.Find(c => c.PKey == $"0x{(FlashIdx + 2).ToString("X4").Replace("2000", "")}"));
                ParaList.Rx_flash_1k.Remove(ParaList.Rx_flash_1k.Find(c => c.PKey == $"0x{(FlashIdx + 3).ToString("X4").Replace("2000", "")}"));
            }
            index = ParaList.Rx_flash_1k.FindIndex(c => c.PKey == "0xfffd" && c.PValue == "0x80");
            ParaList.Rx_flash_1k.Insert(index, new XModem.library.ParaModel() { PKey = $"0x{(FlashIdx + 3).ToString("X4").Replace("2000", "")}", PValue = $"0x{t4.ToString("X2")}" });
            ParaList.Rx_flash_1k.Insert(index, new XModem.library.ParaModel() { PKey = $"0x{(FlashIdx + 2).ToString("X4").Replace("2000", "")}", PValue = $"0x{t3.ToString("X2")}" });
            ParaList.Rx_flash_1k.Insert(index, new XModem.library.ParaModel() { PKey = $"0x{(FlashIdx + 1).ToString("X4").Replace("2000", "")}", PValue = $"0x{t2.ToString("X2")}" });
            ParaList.Rx_flash_1k.Insert(index, new XModem.library.ParaModel() { PKey = $"0x{FlashIdx.ToString("X4").Replace("2000", "")}", PValue = $"0x{t1.ToString("X2")}" });
        }

        uint BinToLength = 0x200014c0;

        private void simpleButton15_Click(object sender, EventArgs e)
        {
            if (!sPortTemp.IsOpen)
            {
                DevExpress.XtraEditors.XtraMessageBox.Show("可用端口未打开!");
                return;
            }
            uint temp0 = (uint)SerialSend.ReadRegister(BinToLength, sPortTemp);
            uint temp1 = (uint)SerialSend.ReadRegister(BinToLength + 1, sPortTemp);
            uint temp2 = (uint)SerialSend.ReadRegister(BinToLength + 2, sPortTemp);
            uint temp3 = (uint)SerialSend.ReadRegister(BinToLength + 3, sPortTemp);

            var binLength = $"{temp3.ToString("X2")}{temp2.ToString("X2")}{temp1.ToString("X2")}{temp0.ToString("X2")}";
            textEdit3.Text = binLength;
        }

        private void simpleButton9_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            openFileDialog1.Filter = "TXT Files(*.bin)|*.bin|All Files(*.*)|*.*";
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                textEdit4.Text = openFileDialog1.FileName;
            }

        }

        private void simpleButton12_Click(object sender, EventArgs e)
        {
            if (textEdit5.Text == null || textEdit4.Text == null)
            {
                DevExpress.XtraEditors.XtraMessageBox.Show("请选择文件!");
                return;
            }
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "bin文件（*.bin）|*.bin";
            //设置默认文件类型显示顺序 
            sfd.FilterIndex = 1;
            //保存对话框是否记忆上次打开的目录 
            sfd.RestoreDirectory = true;
            sfd.FileName = "Offline_Burning_Driver_" + $"_{DateTime.Now.ToString("yyyyMMddHHmm")}";
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                
            }
            else
            {
                return;
            }
            List<string> contentList = new List<string>();
            if (File.Exists(Application.StartupPath + "\\Lib\\xc151_header\\hd1-1.txt"))
            {
                using (StreamReader sr = new StreamReader(Application.StartupPath + "\\Lib\\xc151_header\\hd1-1.txt"))
                {
                    string line;
                    while ((line = sr.ReadLine()) != null)
                    {
                        contentList.Add(line);
                    }
                }
            }
            if (patchheader.Count() == 0x10)
            {
                contentList[0xb3] = $"0x00b3,0x{patchheader[8]}";
                contentList[0xb2] = $"0x00b2,0x{patchheader[9]}";
                contentList[0xb1] = $"0x00b1,0x{patchheader[10]}";
                contentList[0xb0] = $"0x00b0,0x{patchheader[11]}";

                contentList[0xb7] = $"0x00b3,0x{patchheader[0]}";
                contentList[0xb6] = $"0x00b2,0x{patchheader[1]}";
                contentList[0xb5] = $"0x00b1,0x{patchheader[2]}";
                contentList[0xb4] = $"0x00b0,0x{patchheader[3]}";

                contentList[0xbb] = $"0x00b3,0x{patchheader[4]}";
                contentList[0xba] = $"0x00b2,0x{patchheader[5]}";
                contentList[0xb9] = $"0x00b1,0x{patchheader[6]}";
                contentList[0xb8] = $"0x00b0,0x{patchheader[7]}";

                contentList[0xbf] = $"0x00b3,0x{patchheader[12]}";
                contentList[0xbe] = $"0x00b2,0x{patchheader[13]}";
                contentList[0xbd] = $"0x00b1,0x{patchheader[14]}";
                contentList[0xbc] = $"0x00b0,0x{patchheader[15]}";
            }
            string filePath = Application.StartupPath + "\\Lib\\xc151_header\\Burnhd.txt"; // 替换为你想要生成的 txt 文件路径

            // 如果文件已经存在，先删除
            if (File.Exists(filePath))
            {
                File.Delete(filePath);
            }
            // 将 list 中的内容写入文件
            File.WriteAllLines(filePath, contentList);

            var hd = Copy_Files_For_Header_Patch_Tool(filePath, true, "00", false, true);
            hd = HeaderTokey(filePath, hd);
            fsmList.Add(new FlashSettingModel()
            {
                fileAddr = "0",
                fileLength = FilePathLengthComplement8(hd),
                fileName = hd,
            });

            contentList = new List<string>();
            if (File.Exists(hd))
            {
                using (StreamReader sr = new StreamReader(hd))
                {
                    string line;
                    while ((line = sr.ReadLine()) != null)
                    {
                        contentList.Add(line);
                    }
                }
            }
            UInt32 tempy = Convert.ToUInt32(FilePathLengthComplement(PathFile), 16) % 0x1000;
            var fileLengthhd = (0x1000 - tempy + Convert.ToUInt32(FilePathLengthComplement(PathFile), 16)).ToString("X4");
            fsmList.Add(new FlashSettingModel()
            {
                fileAddr = "1000",
                fileLength = fileLengthhd,
                fileName = PathFile,
            });
            string secondFileName = textEdit4.Text; // 数据包文件
            string secondFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, secondFileName);


            FileInfo fileInfo = new FileInfo(secondFilePath);
            long fileLengthbin = fileInfo.Length;
            contentList[218] = "0x00000000";
            contentList[576] = "0x"+ SetLitter((Convert.ToInt32(fsmList[1].fileAddr, 16) + Convert.ToInt32(fsmList[1].fileLength, 16)).ToString("X8"));
            contentList[577] = "0x"+ SetLitter(fileLengthbin.ToString("X8"));
            if (File.Exists(hd))
            {
                File.Delete(hd);
            }
            File.WriteAllLines(hd, contentList);

           
            Setting2FlashE2prom.FlashSetting2Bin(Application.StartupPath + "\\Lib\\xc151_Bin\\Burnhd_Path.bin", fsmList, 1);

            string firstFileName = Application.StartupPath + "\\Lib\\xc151_Bin\\Burnhd_Path.bin"; 
            string outputFileName = sfd.FileName; // 输出的拼接后的二进制文件名

            string firstFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, firstFileName);
            string outputFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, outputFileName);

            byte[] firstFileBytes = File.ReadAllBytes(firstFilePath);
            byte[] secondFileBytes = File.ReadAllBytes(secondFilePath);

            using (FileStream fs = new FileStream(outputFilePath, FileMode.Create))
            {
                fs.Write(firstFileBytes, 0, firstFileBytes.Length);
                fs.Write(secondFileBytes, 0, secondFileBytes.Length);
            }
            fsmList = new List<FlashSettingModel>();
            textEdit4.Text = null;
            textEdit5.Text = null;
            DevExpress.XtraEditors.XtraMessageBox.Show("生成完毕!");
        }
        string HeaderTokey(string pSavePath, string path)
        {
            uint headerKey = 0x368; //头文件存放地址
            uint headerLength = 0x320; //头文件生成长度228行固定 带crc
            //随机范围
            uint headerMax = 0x1000 - headerLength;
            Random rdHear = new Random();
            int rdi = rdHear.Next((int)headerKey + 8, (int)headerMax);
            while (rdi % 4 != 0)
            {
                rdi = rdHear.Next((int)headerKey + 8, (int)headerMax);
            }
            
            rdi = 0;
           
            var IsRandom = ConfigurationManager.AppSettings["IsRandom"] == "0";
            if (IsRandom)
            {
                rdi = 0;
            }
            StringBuilder sb = new StringBuilder();
            if (rdi == 0)
            {
                sb.Append(File.ReadAllText(path));
            }
            else
            {
                var headerList = File.ReadAllLines(path);
                var headerNo = Math.Ceiling(headerList.Count() * 0.2);
                for (int j = 0; j < headerNo; j += 4)
                {
                    sb.Append($"{headerList[j]}\n");

                }
                for (int i = 0; i < headerKey - headerNo; i += 4)
                {

                    if (IsRandom)
                    {
                        var hig1 = (Convert.ToUInt32(Convert.ToByte(rdHear.Next(0, 255))) << 24);
                        var hig2 = (Convert.ToUInt32(Convert.ToByte(0)) << 16);
                        var low1 = (Convert.ToUInt32(Convert.ToByte(rdHear.Next(0, 255))) << 8);
                        var low2 = Convert.ToUInt32(Convert.ToByte(rdHear.Next(0, 255)));
                        long temp = hig1 + hig2 + low1 + low2;
                        sb.Append($"0x{Convert.ToUInt32(temp).ToString("X8")},\n");
                    }
                    else
                    {
                        sb.Append($"0x00000000,\n");
                    }
                }
                //如果没有偏移需要跳过该条赋值不然会多加一条数据进去
                sb.Append($"0x{(rdi & 0xff).ToString("X2")}{(rdi >> 8 & 0xff).ToString("X2")}0000,\n");
                for (int i = 4; i < (rdi - headerKey); i += 4)
                {

                    if (IsRandom)
                    {
                        var hig1 = (Convert.ToUInt32(Convert.ToByte(rdHear.Next(0, 255))) << 24);
                        var hig2 = (Convert.ToUInt32(Convert.ToByte(0)) << 16);
                        var low1 = (Convert.ToUInt32(Convert.ToByte(rdHear.Next(0, 255))) << 8);
                        var low2 = Convert.ToUInt32(Convert.ToByte(rdHear.Next(0, 255)));
                        long temp = hig1 + hig2 + low1 + low2;
                        sb.Append($"0x{Convert.ToUInt32(temp).ToString("X8")},\n");
                    }
                    else
                    {
                        sb.Append($"0x00000000,\n");
                    }
                }

                sb.Append(File.ReadAllText(path));

            }
            for (uint i = Convert.ToUInt32(rdi) + headerLength; i < 0x1000; i += 4)
            {
                if (!IsRandom)
                {
                    var hig1 = (Convert.ToUInt32(Convert.ToByte(rdHear.Next(0, 255))) << 24);
                    var hig2 = (Convert.ToUInt32(Convert.ToByte(0)) << 16);
                    var low1 = (Convert.ToUInt32(Convert.ToByte(rdHear.Next(0, 255))) << 8);
                    var low2 = Convert.ToUInt32(Convert.ToByte(rdHear.Next(0, 255)));
                    long temp = hig1 + hig2 + low1 + low2;
                    sb.Append($"0x{Convert.ToUInt32(temp).ToString("X8")},\n");
                }
                else
                {
                    sb.Append($"0x00000000,\n");
                }

            }
            path = System.IO.Path.GetDirectoryName(pSavePath) + "\\Flash_H_" + Path.GetFileNameWithoutExtension(pSavePath) + ".txt";
            File.WriteAllText(path, sb.ToString());
            return path;
        }

        private void simpleButton13_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            openFileDialog1.Filter = "TXT Files(*.xfw)|*.xfw|All Files(*.*)|*.*";
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                UnZipFile(openFileDialog1.FileName);
                string[] binFiles = Directory.GetFiles($"{Application.StartupPath}\\Lib\\XChip_Zip", "*.bin", SearchOption.AllDirectories);
                if (binFiles.Count() <= 0)
                {
                    Close_Process_ByAll();
                    WaitBefore.Close();
                    return;
                }
                textEdit6.Text = openFileDialog1.FileName;
                string firstMatch = binFiles.FirstOrDefault(s => s.Contains("Patch_Bin"));
                openFileDialog1.FileName = firstMatch;
                //转换过后的TXTpatch文件
                AlternatePathFile = patch_Copy_Files_For_Header_Patch_Tool(openFileDialog1.FileName, true, "", true, false, 4);

            }
        }
        string AlternatePathFile = "";

        private void simpleButton14_Click(object sender, EventArgs e)
        {
            int combox = 0;
            switch (comboBox2.SelectedIndex)
            {
                case 0:
                    combox = 64;
                    break;
                case 1:
                    combox = 128;
                    break;
                case 2:
                    combox = 256;
                    break;
                case 3:
                    combox = 512;
                    break;
                case 4:
                    combox = 1024;
                    break;
                case 5:
                    combox = 2048;
                    break;
                case 6:
                    combox = 4096;
                    break;
                case 7:
                    combox = 8192;
                    break;
                default:
                    break;
            }
            List<string> contentList = new List<string>();
            contentList.Add("0x51014358,");
            contentList.Add("0x00000000,");
            contentList.Add("0x"+ SetLitter((combox * 1024 - 0x2000 + 0x1c).ToString("X8")));
            contentList.Add("0x"+patchheader[11]+ patchheader[10]+ patchheader[9]+ patchheader[8]);
            contentList.Add("0x" + patchheader[3] + patchheader[2] + patchheader[1] + patchheader[0]);
            contentList.Add("0x" + patchheader[7] + patchheader[6] + patchheader[5] + patchheader[4]);
            contentList.Add("0x" + patchheader[15] + patchheader[14] + patchheader[13] + patchheader[12]);
            if (File.Exists(AlternatePathFile))
            {
                using (StreamReader sr = new StreamReader(AlternatePathFile))
                {
                    string line;
                    while ((line = sr.ReadLine()) != null)
                    {
                        contentList.Add(line);
                    }
                }
            }
            // 如果文件已经存在，先删除
            if (File.Exists(Application.StartupPath + "\\Lib\\xc151_setting\\AlternatePathFile.txt"))
            {
                File.Delete(Application.StartupPath + "\\Lib\\xc151_setting\\AlternatePathFile.txt");
            }
            // 将 list 中的内容写入文件
            File.WriteAllLines(Application.StartupPath + "\\Lib\\xc151_setting\\AlternatePathFile.txt", contentList);
            List<FlashSettingModel> fsmLista = new List<FlashSettingModel>();
            fsmLista.Add(new FlashSettingModel()
            {
                fileAddr = "0",
                fileLength = FilePathLengthComplement(Application.StartupPath + "\\Lib\\xc151_setting\\AlternatePathFile.txt"),
                fileName = Application.StartupPath + "\\Lib\\xc151_setting\\AlternatePathFile.txt",
            });
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "bin文件（*.bin）|*.bin";
            //设置默认文件类型显示顺序 
            sfd.FilterIndex = 1;
            //保存对话框是否记忆上次打开的目录 
            sfd.RestoreDirectory = true;
            sfd.FileName = "AlternatePath_" + $"_{DateTime.Now.ToString("yyyyMMddHHmm")}";
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                Setting2FlashE2prom.FlashSetting2Bin(sfd.FileName, fsmLista, 1);
                textEdit6.Text = null;
                DevExpress.XtraEditors.XtraMessageBox.Show("生成完毕!");
            }
            else
            {
                return;
            }
            
        }

        private void checkEdit1_CheckedChanged(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(textEdit1.Text))
            {
                DevExpress.XtraEditors.XtraMessageBox.Show("请先导入bin文件！");
                checkEdit1.Checked = false;
                return;
            }
            if (checkEdit1.Checked)
            {
                if (!sPortTemp.IsOpen)
                {
                    DevExpress.XtraEditors.XtraMessageBox.Show("可用端口未打开!");
                    return;
                }
                //勾选起始地址后需要读取0x2000026a~0x2000026b的值，如果是0xabcd就让用户填写烧录地址，然后进行自定义烧录操作。
                var nhdr_l = SerialSend.ReadRegister(0x2000026a, sPortTemp);
                var nhdr_h = SerialSend.ReadRegister(0x2000026b, sPortTemp);
                if (nhdr_l == 0x0 || nhdr_h == 0x0)
                {
                    subsectioncheck.Checked = false;
                    checkEdit1.Checked = false;
                    DevExpress.XtraEditors.XtraMessageBox.Show("模组Patch未支持备用补丁功能!");
                    return;
                }
                subsectioncheck.Checked = true;
                subsectiontext.Enabled = true;
                byte[] firstFileBytes = File.ReadAllBytes(textEdit1.Text);
                var AlternateAddr = ((firstFileBytes[11] << 24) | (firstFileBytes[10] << 16) | (firstFileBytes[9] << 8) | firstFileBytes[8]) - 0x1c;
                subsectiontext.Text = AlternateAddr.ToString("X8");
            }
            else
            {
                subsectiontext.Text = string.Empty;
                subsectiontext.Enabled = false;
            }
        }
        static void OnWriteCompleted(bool success, int status)
        {
            // 根据 success 和 status 设置 Task 的结果  
            if (success && status == 100)
            {
                _writeTaskCompletionSource.SetResult(true); // 写入成功  
            }
            else
            {
                _writeTaskCompletionSource.SetResult(false); // 写入失败  
                                                             // 注意：这里也可以考虑使用 SetException 来抛出异常，但那样需要捕获 Task 的异常  
            }
        }
    }
}
